ratch 1.1.0 → 1.2.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.ruby +99 -0
- data/COPYING +203 -21
- data/History.rdoc +35 -0
- data/License.txt +204 -0
- data/README.rdoc +113 -0
- data/Version +1 -0
- data/bin/ludo +16 -0
- data/bin/ratch +1 -8
- data/lib/ratch.rb +28 -0
- data/lib/ratch.yml +99 -0
- data/lib/ratch/batch.rb +500 -0
- data/lib/ratch/console.rb +199 -0
- data/lib/ratch/core_ext.rb +1 -4
- data/lib/ratch/core_ext/facets.rb +15 -1
- data/lib/ratch/core_ext/filetest.rb +29 -0
- data/lib/ratch/core_ext/{string.rb → to_actual_filename.rb} +0 -23
- data/lib/ratch/core_ext/to_console.rb +30 -12
- data/lib/ratch/core_ext/{object.rb → to_yamlfrag.rb} +1 -0
- data/lib/ratch/core_ext/unfold_paragraphs.rb +27 -0
- data/lib/ratch/file_list.rb +411 -0
- data/lib/ratch/script.rb +99 -5
- data/lib/ratch/script/help.rb +84 -0
- data/lib/ratch/shell.rb +783 -0
- data/lib/ratch/system.rb +15 -0
- data/lib/ratch/utils/cli.rb +49 -0
- data/lib/ratch/utils/config.rb +52 -0
- data/lib/ratch/{emailer.rb → utils/email.rb} +43 -6
- data/lib/ratch/utils/ftp.rb +134 -0
- data/lib/ratch/utils/pom.rb +22 -0
- data/lib/ratch/utils/rdoc.rb +48 -0
- data/lib/ratch/utils/tar.rb +88 -0
- data/lib/ratch/utils/xdg.rb +39 -0
- data/lib/ratch/utils/zlib.rb +54 -0
- data/spec/01_shell.rdoc +198 -0
- data/spec/02_script.rdoc +34 -0
- data/spec/03_batch.rdoc +71 -0
- data/spec/04_system.rdoc +3 -0
- data/spec/applique/array.rb +8 -0
- data/spec/applique/setup.rb +20 -0
- data/test/case_batch.rb +63 -0
- data/test/case_shell.rb +46 -0
- data/test/core_ext/case_pathname.rb +361 -0
- data/test/helper.rb +4 -0
- data/test/utils/case_cli.rb +6 -0
- data/test/utils/case_config.rb +12 -0
- data/test/utils/case_email.rb +10 -0
- data/test/utils/case_ftp.rb +6 -0
- data/test/utils/case_pom.rb +17 -0
- data/test/utils/case_rdoc.rb +23 -0
- data/test/utils/case_tar.rb +6 -0
- data/test/utils/case_zlib.rb +11 -0
- data/test/utils/fixtures/pom_sample/Profile +4 -0
- data/test/utils/fixtures/rdoc_sample/README.rdoc +4 -0
- data/test/utils/fixtures/rdoc_sample/lib/rdoc_sample/rdoc_sample.rb +9 -0
- metadata +139 -82
- data/HISTORY +0 -6
- data/MANIFEST +0 -53
- data/NEWS +0 -12
- data/README +0 -87
- data/VERSION +0 -1
- data/demo/tryme-task.ratch +0 -12
- data/demo/tryme1.ratch +0 -6
- data/doc/log/basic_stats/index.html +0 -39
- data/doc/log/notes.xml +0 -18
- data/doc/log/stats.log +0 -14
- data/doc/log/syntax.log +0 -0
- data/doc/log/testunit.log +0 -156
- data/lib/ratch/commandline.rb +0 -16
- data/lib/ratch/core_ext/pathname.rb +0 -38
- data/lib/ratch/dsl.rb +0 -420
- data/lib/ratch/index.rb +0 -4
- data/lib/ratch/io.rb +0 -116
- data/lib/ratch/plugin.rb +0 -65
- data/lib/ratch/service.rb +0 -33
- data/lib/ratch/task.rb +0 -249
- data/lib/ratch/task2.rb +0 -298
- data/meta/abstract +0 -4
- data/meta/author +0 -1
- data/meta/contact +0 -1
- data/meta/homepage +0 -1
- data/meta/name +0 -1
- data/meta/requires +0 -4
- data/meta/summary +0 -1
- data/test/README +0 -1
- data/test/test_helper.rb +0 -4
- data/test/test_task.rb +0 -46
@@ -0,0 +1,39 @@
|
|
1
|
+
module Ratch
|
2
|
+
|
3
|
+
# The XDG utility module provides access ot the XDG library functions.
|
4
|
+
# This module requires the `xdg` gem.
|
5
|
+
#
|
6
|
+
# This module simply maps the #xdg method to the XDG function module.
|
7
|
+
#
|
8
|
+
# NOTE: This module is non-essential since one can just use
|
9
|
+
# the XDG module directly, however we want to encourage the
|
10
|
+
# use XDG, so it's been provided to encourage that in the context
|
11
|
+
# of a Ratch script.
|
12
|
+
#
|
13
|
+
module XDGUtils
|
14
|
+
|
15
|
+
def self.included(base)
|
16
|
+
begin
|
17
|
+
require 'xdg'
|
18
|
+
rescue
|
19
|
+
$stderr << "The `xdg` gem is needed to use the XDGUtils module."
|
20
|
+
exit -1
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def self.extended(base)
|
25
|
+
included(base)
|
26
|
+
end
|
27
|
+
|
28
|
+
# Simple access to XDG function module.
|
29
|
+
#
|
30
|
+
# xdg.config.home #=> "~/.config"
|
31
|
+
#
|
32
|
+
def xdg
|
33
|
+
XDG
|
34
|
+
end
|
35
|
+
|
36
|
+
end
|
37
|
+
|
38
|
+
end
|
39
|
+
|
@@ -0,0 +1,54 @@
|
|
1
|
+
module Ratch
|
2
|
+
|
3
|
+
#
|
4
|
+
module ZlibUtils
|
5
|
+
|
6
|
+
#
|
7
|
+
def self.included(base)
|
8
|
+
require 'zlib'
|
9
|
+
end
|
10
|
+
|
11
|
+
def self.extended(base)
|
12
|
+
included(base)
|
13
|
+
end
|
14
|
+
|
15
|
+
# Create a gzip file.
|
16
|
+
def gzip(file, tofile=nil, options={})
|
17
|
+
noop, verbose = *util_options(options)
|
18
|
+
|
19
|
+
tofile ||= File.basename(file) + '.gz'
|
20
|
+
|
21
|
+
puts "gzip #{file}" if verbose
|
22
|
+
|
23
|
+
file = localize(file)
|
24
|
+
tofile = localize(tofile)
|
25
|
+
|
26
|
+
Zlib::GzipWriter.open(tofile) do |gz|
|
27
|
+
gz.write(File.read(file))
|
28
|
+
end unless noop
|
29
|
+
|
30
|
+
return tofile
|
31
|
+
end
|
32
|
+
|
33
|
+
# Unpack a gzip file.
|
34
|
+
def ungzip(file, options={})
|
35
|
+
noop, verbose = *util_options(options)
|
36
|
+
|
37
|
+
fname = File.basename(file).chomp(File.extname(file))
|
38
|
+
|
39
|
+
puts "ungzip #{file}" if verbose
|
40
|
+
|
41
|
+
fname = localize(fname)
|
42
|
+
file = localize(file)
|
43
|
+
|
44
|
+
Zlib::GzipReader.open(file) do |gz|
|
45
|
+
File.open(fname, 'wb'){ |f| f << gz.read }
|
46
|
+
end unless noop
|
47
|
+
|
48
|
+
return fname
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
54
|
+
|
data/spec/01_shell.rdoc
ADDED
@@ -0,0 +1,198 @@
|
|
1
|
+
= Ratch::Shell
|
2
|
+
|
3
|
+
The Shell class mimics a basic shell command line prompt.
|
4
|
+
|
5
|
+
require 'ratch/shell'
|
6
|
+
|
7
|
+
The demonstration sets up sample directory consisting of the following
|
8
|
+
entires in the tmp/qed directory:
|
9
|
+
|
10
|
+
foo.txt
|
11
|
+
zoo/
|
12
|
+
zoo/bar.txt
|
13
|
+
|
14
|
+
== Initial Path
|
15
|
+
|
16
|
+
When no path argument is provided to the initializer, the present working path
|
17
|
+
is used. The path is stored as a Pathname object.
|
18
|
+
|
19
|
+
shell = Ratch::Shell.new
|
20
|
+
shell.work.assert = Pathname.new(Dir.pwd).expand_path
|
21
|
+
|
22
|
+
Otherwise the path given is used.
|
23
|
+
|
24
|
+
shell = Ratch::Shell.new('.')
|
25
|
+
shell.work.assert = Pathname.new('.').expand_path
|
26
|
+
|
27
|
+
shell = Ratch::Shell.new('..')
|
28
|
+
shell.work.assert = Pathname.new('..').expand_path
|
29
|
+
|
30
|
+
An error is raise if the path does not exist.
|
31
|
+
|
32
|
+
expect Ratch::FileNotFound do
|
33
|
+
Ratch::Shell.new('not_a_path')
|
34
|
+
end
|
35
|
+
|
36
|
+
== Processing Options
|
37
|
+
|
38
|
+
The +initialize+ method accepts a few options. The +quiet+ option supresses
|
39
|
+
all output to stdout.
|
40
|
+
|
41
|
+
shell = Ratch::Shell.new(:quiet=>true)
|
42
|
+
shell.assert.quiet?
|
43
|
+
|
44
|
+
The +noop+ option prevents any actual writing to disk --the process will
|
45
|
+
simply pretend that it has done so.
|
46
|
+
|
47
|
+
shell = Ratch::Shell.new(:noop=>true)
|
48
|
+
shell.assert.noop?
|
49
|
+
|
50
|
+
The +trace+ option provides step by step feedback on what is taking place.
|
51
|
+
|
52
|
+
shell = Ratch::Shell.new(:trace=>true)
|
53
|
+
shell.assert.trace?
|
54
|
+
|
55
|
+
The +dryrun+ option is simply a compbination of +noop+ and +trace+.
|
56
|
+
|
57
|
+
shell = Ratch::Shell.new(:dryrun=>true)
|
58
|
+
shell.assert.noop?
|
59
|
+
shell.assert.trace?
|
60
|
+
shell.assert.dryrun?
|
61
|
+
|
62
|
+
== Equality
|
63
|
+
|
64
|
+
For two Shell objects to be considered equal, via #==, they must both
|
65
|
+
be instances of Ratch::Shell (or subclass) and have the same working
|
66
|
+
path.
|
67
|
+
|
68
|
+
shell1 = Ratch::Shell.new('.')
|
69
|
+
shell2 = Ratch::Shell.new('.')
|
70
|
+
shell1.assert = shell2
|
71
|
+
|
72
|
+
shell1 = Ratch::Shell.new('.')
|
73
|
+
shell2 = Ratch::Shell.new('..')
|
74
|
+
shell1.refute = shell2
|
75
|
+
|
76
|
+
The more strict #eql? method also ensures that the +noop+ option is the same.
|
77
|
+
|
78
|
+
shell1 = Ratch::Shell.new('.', :noop=>true)
|
79
|
+
shell2 = Ratch::Shell.new('.', :noop=>true)
|
80
|
+
shell1.assert.eql? shell2
|
81
|
+
|
82
|
+
shell1 = Ratch::Shell.new('.', :noop=>true)
|
83
|
+
shell2 = Ratch::Shell.new('.', :noop=>false)
|
84
|
+
shell1.refute.eql? shell2
|
85
|
+
|
86
|
+
== File System Locations
|
87
|
+
|
88
|
+
The Shell class provides a few convenient methods for accessing common
|
89
|
+
locations in the file system, namely #work, #home, #parent and #root.
|
90
|
+
|
91
|
+
shell = Ratch::Shell.new
|
92
|
+
|
93
|
+
shell.work.assert == Pathname.new('.').expand_path
|
94
|
+
shell.parent.assert == Pathname.new('..').expand_path
|
95
|
+
|
96
|
+
The current user's home directoryis accessible via the #home method.
|
97
|
+
|
98
|
+
shell.home.assert == Pathname.new('~').expand_path
|
99
|
+
|
100
|
+
The system's root folder can be accessed via #root method.
|
101
|
+
|
102
|
+
shell.root.assert == Pathname.new('/').expand_path
|
103
|
+
|
104
|
+
In addition the Shell class provides methods for accessing pathnames
|
105
|
+
relative to the current shell directory. The #path (or #pathname) method
|
106
|
+
returns a Pathname object with the given path.
|
107
|
+
|
108
|
+
shell.path('foo')
|
109
|
+
|
110
|
+
This will work regardless if the path actually exists or not. On the other hand,
|
111
|
+
the #file and #dir methods will do the same, but will raise an error if the path
|
112
|
+
given is not an existing file or a directory, respectively.
|
113
|
+
|
114
|
+
shell.file('foo.txt')
|
115
|
+
|
116
|
+
expect Ratch::FileNotFound do
|
117
|
+
shell.file('not.txt')
|
118
|
+
end
|
119
|
+
|
120
|
+
shell.dir('zoo')
|
121
|
+
|
122
|
+
expect Ratch::FileNotFound do
|
123
|
+
shell.dir('not')
|
124
|
+
end
|
125
|
+
|
126
|
+
== Entries
|
127
|
+
|
128
|
+
Shell#entries works just like Dir.entries except that each path is returned
|
129
|
+
as a Pathname object.
|
130
|
+
|
131
|
+
shell = Ratch::Shell.new
|
132
|
+
|
133
|
+
shell.entries.assert == ['foo.txt', '.', '..', 'zoo'].map{|f| Pathname.new(f)}
|
134
|
+
|
135
|
+
The #file_entries method limits the list to files only.
|
136
|
+
|
137
|
+
shell.file_entries.assert == ['foo.txt'].map{|f| Pathname.new(f)}
|
138
|
+
|
139
|
+
Whereas #directory_entries (or #dir_entries) limits the list to directories.
|
140
|
+
|
141
|
+
shell.directory_entries.assert == ['.', '..', 'zoo'].map{|f| Pathname.new(f)}
|
142
|
+
|
143
|
+
Of course, having to deal with the '.' and '..' is annoying most of the time
|
144
|
+
so Shell provides more convenient methods. Like #entries, #pathnames
|
145
|
+
provides a list of entries less the dot paths.
|
146
|
+
|
147
|
+
shell.pathnames.assert == ['foo.txt', 'zoo'].map{|f| Pathname.new(f)}
|
148
|
+
|
149
|
+
The #directories (also #folders) method limits this list to directories only.
|
150
|
+
|
151
|
+
shell.directories.assert == ['zoo'].map{|f| Pathname.new(f)}
|
152
|
+
|
153
|
+
And #files works out to be the same as #file_entires.
|
154
|
+
|
155
|
+
shell.files.assert == ['foo.txt'].map{|f| Pathname.new(f)}
|
156
|
+
|
157
|
+
== Globbing
|
158
|
+
|
159
|
+
shell = Ratch::Shell.new
|
160
|
+
|
161
|
+
shell.glob('*').assert == ['foo.txt', 'zoo']
|
162
|
+
|
163
|
+
== File Testing
|
164
|
+
|
165
|
+
Shell provides an interface to most of FileTest's functions.
|
166
|
+
|
167
|
+
shell.assert.exist?('foo.txt')
|
168
|
+
shell.assert.file?('foo.txt')
|
169
|
+
shell.refute.directory?('foo.txt')
|
170
|
+
shell.assert.directory?('zoo')
|
171
|
+
|
172
|
+
== File IO
|
173
|
+
|
174
|
+
Shell can be used to easily read the contents of a file.
|
175
|
+
|
176
|
+
shell = Ratch::Shell.new
|
177
|
+
|
178
|
+
shell.read('foo.txt').assert == 'SAMPLE FOO.TXT'
|
179
|
+
|
180
|
+
As well as write a new file.
|
181
|
+
|
182
|
+
shell.write('baz.txt', 'BAZ TEXT')
|
183
|
+
shell.read('baz.txt').assert == 'BAZ TEXT'
|
184
|
+
|
185
|
+
Or append to an existing file.
|
186
|
+
|
187
|
+
shell.append('baz.txt', ' 2')
|
188
|
+
shell.read('baz.txt').assert == 'BAZ TEXT 2'
|
189
|
+
|
190
|
+
The shell command supports many file methods, including #rm.
|
191
|
+
|
192
|
+
shell.rm('baz.txt')
|
193
|
+
|
194
|
+
== System Calls
|
195
|
+
|
196
|
+
The Shell class can also call out to system commands. This is handled
|
197
|
+
by the Ratch::System class. See the system.rdoc file for details.
|
198
|
+
|
data/spec/02_script.rdoc
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
= Ratch::Script
|
2
|
+
|
3
|
+
The Ratch::Script class is the context used for evaluating Ratch-based
|
4
|
+
batch files, aka shell scripts.
|
5
|
+
|
6
|
+
require 'ratch/script'
|
7
|
+
|
8
|
+
In most every respect the Script class behaves like Ratch::Shell, except that
|
9
|
+
its initializer takes a file name to be evaluated.
|
10
|
+
|
11
|
+
Let's say we have a Ratch script called 'foo.ratch':
|
12
|
+
|
13
|
+
#!/usr/bin/env ratch
|
14
|
+
|
15
|
+
@test_message = "Hello World!"
|
16
|
+
|
17
|
+
We can load the script via Ratch::Script.new.
|
18
|
+
|
19
|
+
script = Ratch::Script.new('foo.ratch')
|
20
|
+
|
21
|
+
The file name can be accessed from the script using #script_file.
|
22
|
+
|
23
|
+
script.script_file.assert == 'foo.ratch'
|
24
|
+
|
25
|
+
To execute a script, use the `#execute!` method, or it's alias `#run!`.
|
26
|
+
|
27
|
+
script.execute!
|
28
|
+
|
29
|
+
We can see that the script did indeed execute by plubming for the instance
|
30
|
+
variable it set.
|
31
|
+
|
32
|
+
msg = script.instance_variable_get('@test_message')
|
33
|
+
msg.assert == "Hello World!"
|
34
|
+
|
data/spec/03_batch.rdoc
ADDED
@@ -0,0 +1,71 @@
|
|
1
|
+
= Ratch::Batch
|
2
|
+
|
3
|
+
The Batch class makes makes it possible to work with multiple files
|
4
|
+
at once as easily as one would work with a single file.
|
5
|
+
|
6
|
+
require 'ratch/batch'
|
7
|
+
|
8
|
+
The demonstration sets up a sample directory consisting of the following
|
9
|
+
entires in the temporary working directory:
|
10
|
+
|
11
|
+
foo.txt
|
12
|
+
bar.txt
|
13
|
+
zoo/
|
14
|
+
zoo/one.txt
|
15
|
+
zoo/two.txt
|
16
|
+
|
17
|
+
To create a new Batch instance, pass the the base directory and any
|
18
|
+
inclusion patterns to the initializer.
|
19
|
+
|
20
|
+
batch = Ratch::Batch.new('.', '*.txt')
|
21
|
+
|
22
|
+
In this example we will get every `.txt` file at the toplevel of the base
|
23
|
+
directory.
|
24
|
+
|
25
|
+
batch.to_a.assert = ['foo.txt', 'bar.txt'].to_pathnames
|
26
|
+
|
27
|
+
To get a list of files relative to the base directory, use #entries.
|
28
|
+
|
29
|
+
batch.entries.assert = ['foo.txt', 'bar.txt'].to_pathnames
|
30
|
+
|
31
|
+
Internally a Batch instance tracks the files selected via a Ratch::FileList
|
32
|
+
object. This can be directly accessed via the #list method.
|
33
|
+
|
34
|
+
batch.file_list.assert.is_a?(Ratch::FileList)
|
35
|
+
|
36
|
+
batch.file_list.to_a.assert = ['foo.txt', 'bar.txt']
|
37
|
+
|
38
|
+
As with the delegated FileTest methods of the Shell class, Batch can test
|
39
|
+
the set of files in agregate. For example, to ensure all the entries
|
40
|
+
are files we can use the #file? method.
|
41
|
+
|
42
|
+
batch.assert.file?
|
43
|
+
|
44
|
+
Likewise to enusre none the entires are directories we can use the #directory?
|
45
|
+
method.
|
46
|
+
|
47
|
+
batch.refute.directory?
|
48
|
+
|
49
|
+
The Batch list can be reduced to just files or just directories via the #file!
|
50
|
+
and #directory! methods.
|
51
|
+
|
52
|
+
batch = Ratch::Batch.new('.', '*')
|
53
|
+
batch.file!
|
54
|
+
batch.list.assert = ['foo.txt', 'bar.txt']
|
55
|
+
|
56
|
+
batch = Ratch::Batch.new('.', '*')
|
57
|
+
batch.directory!
|
58
|
+
batch.list.assert = ['zoo']
|
59
|
+
|
60
|
+
The Batch class is enumerable, both #each and #size are defined.
|
61
|
+
|
62
|
+
batch = Ratch::Batch.new('.', '*.txt')
|
63
|
+
|
64
|
+
batch.each do |pathname|
|
65
|
+
pathname.assert.is_a?(Pathname)
|
66
|
+
end
|
67
|
+
|
68
|
+
batch.size.assert = 2
|
69
|
+
|
70
|
+
Any enumerable method is likewise applicable.
|
71
|
+
|
data/spec/04_system.rdoc
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'fileutils'
|
2
|
+
|
3
|
+
Before :demo do
|
4
|
+
clear_working_directory!
|
5
|
+
end
|
6
|
+
|
7
|
+
When "consisting of the following entires" do |text|
|
8
|
+
text.split(/\s+/).each do |file|
|
9
|
+
if /\/$/ =~ file
|
10
|
+
FileUtils.mkdir_p(file) unless File.directory?(file)
|
11
|
+
else
|
12
|
+
File.open(file, 'w+'){ |f| f << "SAMPLE #{file}".upcase }
|
13
|
+
end
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
When "Let's say we have a Ratch script called '(((.*?)))'" do |file, text|
|
18
|
+
File.open(file, 'w'){ |f| f << text }
|
19
|
+
end
|
20
|
+
|
data/test/case_batch.rb
ADDED
@@ -0,0 +1,63 @@
|
|
1
|
+
require 'ratch/batch'
|
2
|
+
|
3
|
+
KO.case Ratch::Batch do
|
4
|
+
|
5
|
+
def initialize
|
6
|
+
stage_clear
|
7
|
+
stage_fake %w{a.txt b.txt d/x.txt d/y.txt}
|
8
|
+
|
9
|
+
@batch1 = Ratch::Batch.new('.')
|
10
|
+
@batch2 = Ratch::Batch.new('.', '*')
|
11
|
+
@batch3 = Ratch::Batch.new('.', '**/*')
|
12
|
+
end
|
13
|
+
|
14
|
+
test :local do
|
15
|
+
@batch1.local == Pathname.new('.')
|
16
|
+
end
|
17
|
+
|
18
|
+
test :list do
|
19
|
+
@batch1.list.is_a?(Array)
|
20
|
+
end
|
21
|
+
|
22
|
+
test :file_list do
|
23
|
+
@batch1.file_list.is_a?(Ratch::FileList)
|
24
|
+
end
|
25
|
+
|
26
|
+
test :each do
|
27
|
+
r = []
|
28
|
+
@batch2.each{ |pn| r << pn }
|
29
|
+
r.map(&:to_s).sort == %w{a.txt b.txt d}
|
30
|
+
end
|
31
|
+
|
32
|
+
test "passes #each thru to Enumerable methods" do
|
33
|
+
@batch2.all?{ |pn| pn.is_a? Pathname }
|
34
|
+
end
|
35
|
+
|
36
|
+
test :size do
|
37
|
+
batch = Ratch::Batch.new('.', '*')
|
38
|
+
batch.size == 3
|
39
|
+
end
|
40
|
+
|
41
|
+
test :directory? do
|
42
|
+
batch = Ratch::Batch.new('.', '*')
|
43
|
+
not batch.directory?
|
44
|
+
end
|
45
|
+
|
46
|
+
test :file? do
|
47
|
+
not @batch2.file?
|
48
|
+
end
|
49
|
+
|
50
|
+
test :directory! do
|
51
|
+
batch = Ratch::Batch.new('.', '*')
|
52
|
+
batch.directory!
|
53
|
+
batch.filenames == %w{d}
|
54
|
+
end
|
55
|
+
|
56
|
+
test :file! do
|
57
|
+
batch = Ratch::Batch.new('.', '*')
|
58
|
+
batch.file!
|
59
|
+
batch.filenames.sort == %w{a.txt b.txt}
|
60
|
+
end
|
61
|
+
|
62
|
+
end
|
63
|
+
|