rush 0.1
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/Rakefile +86 -0
- data/bin/rush +6 -0
- data/bin/rushd +6 -0
- data/lib/rush.rb +20 -0
- data/lib/rush/array_ext.rb +17 -0
- data/lib/rush/box.rb +63 -0
- data/lib/rush/commands.rb +55 -0
- data/lib/rush/config.rb +154 -0
- data/lib/rush/dir.rb +148 -0
- data/lib/rush/entry.rb +141 -0
- data/lib/rush/file.rb +73 -0
- data/lib/rush/fixnum_ext.rb +18 -0
- data/lib/rush/head_tail.rb +11 -0
- data/lib/rush/local.rb +224 -0
- data/lib/rush/process.rb +39 -0
- data/lib/rush/remote.rb +105 -0
- data/lib/rush/search_results.rb +58 -0
- data/lib/rush/server.rb +81 -0
- data/lib/rush/shell.rb +123 -0
- data/lib/rush/ssh_tunnel.rb +113 -0
- data/lib/rush/string_ext.rb +3 -0
- data/spec/array_ext_spec.rb +15 -0
- data/spec/base.rb +24 -0
- data/spec/box_spec.rb +18 -0
- data/spec/commands_spec.rb +47 -0
- data/spec/config_spec.rb +108 -0
- data/spec/dir_spec.rb +148 -0
- data/spec/entry_spec.rb +118 -0
- data/spec/file_spec.rb +75 -0
- data/spec/fixnum_ext_spec.rb +19 -0
- data/spec/local_spec.rb +196 -0
- data/spec/process_spec.rb +44 -0
- data/spec/remote_spec.rb +84 -0
- data/spec/search_results_spec.rb +44 -0
- data/spec/shell_spec.rb +12 -0
- data/spec/ssh_tunnel_spec.rb +106 -0
- data/spec/string_ext_spec.rb +23 -0
- metadata +91 -0
data/spec/file_spec.rb
ADDED
@@ -0,0 +1,75 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/base'
|
2
|
+
|
3
|
+
describe Rush::File do
|
4
|
+
before do
|
5
|
+
@sandbox_dir = "/tmp/rush_spec.#{Process.pid}"
|
6
|
+
system "rm -rf #{@sandbox_dir}; mkdir -p #{@sandbox_dir}"
|
7
|
+
|
8
|
+
@filename = "#{@sandbox_dir}/test_file"
|
9
|
+
@contents = "1234"
|
10
|
+
system "echo #{@contents} > #{@filename}"
|
11
|
+
@contents += "\n"
|
12
|
+
|
13
|
+
@file = Rush::File.new(@filename)
|
14
|
+
end
|
15
|
+
|
16
|
+
after do
|
17
|
+
system "rm -rf #{@sandbox_dir}"
|
18
|
+
end
|
19
|
+
|
20
|
+
it "is a child of Rush::Entry" do
|
21
|
+
@file.should be_kind_of(Rush::Entry)
|
22
|
+
end
|
23
|
+
|
24
|
+
it "is not a dir" do
|
25
|
+
@file.should_not be_dir
|
26
|
+
end
|
27
|
+
|
28
|
+
it "can create itself as a blank file, and return itself" do
|
29
|
+
create_me = Rush::File.new("#{@sandbox_dir}/create_me")
|
30
|
+
create_me.create.should == create_me
|
31
|
+
File.exists?("#{@sandbox_dir}/create_me").should == true
|
32
|
+
end
|
33
|
+
|
34
|
+
it "knows its size in bytes" do
|
35
|
+
@file.size.should == @contents.length
|
36
|
+
end
|
37
|
+
|
38
|
+
it "can read its contents" do
|
39
|
+
@file.contents.should == @contents
|
40
|
+
end
|
41
|
+
|
42
|
+
it "can write new contents" do
|
43
|
+
@file.write('write test')
|
44
|
+
@file.contents.should == 'write test'
|
45
|
+
end
|
46
|
+
|
47
|
+
it "can count the number of lines it contains" do
|
48
|
+
@file.write("1\n2\n3\n")
|
49
|
+
@file.line_count.should == 3
|
50
|
+
end
|
51
|
+
|
52
|
+
it "searches its contents for matching lines" do
|
53
|
+
@file.write("a\n1\nb\n2\n")
|
54
|
+
@file.search(/\d/).should == %w(1 2)
|
55
|
+
end
|
56
|
+
|
57
|
+
it "search returns nil if no lines match" do
|
58
|
+
@file.write("a\nb\nc\n")
|
59
|
+
@file.search(/\d/).should be_nil
|
60
|
+
end
|
61
|
+
|
62
|
+
it "find-in-file replace" do
|
63
|
+
@file.replace_contents!(/\d/, 'x')
|
64
|
+
@file.contents.should == "xxxx\n"
|
65
|
+
end
|
66
|
+
|
67
|
+
it "can destroy itself" do
|
68
|
+
@file.destroy
|
69
|
+
::File.exists?(@filename).should be_false
|
70
|
+
end
|
71
|
+
|
72
|
+
it "can fetch contents or blank if doesn't exist" do
|
73
|
+
Rush::File.new('/does/not/exist').contents_or_blank.should == ""
|
74
|
+
end
|
75
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/base'
|
2
|
+
|
3
|
+
describe Fixnum do
|
4
|
+
before do
|
5
|
+
@num = 2
|
6
|
+
end
|
7
|
+
|
8
|
+
it "counts kb" do
|
9
|
+
@num.kb.should == 2*1024
|
10
|
+
end
|
11
|
+
|
12
|
+
it "counts mb" do
|
13
|
+
@num.mb.should == 2*1024*1024
|
14
|
+
end
|
15
|
+
|
16
|
+
it "counts gb" do
|
17
|
+
@num.gb.should == 2*1024*1024*1024
|
18
|
+
end
|
19
|
+
end
|
data/spec/local_spec.rb
ADDED
@@ -0,0 +1,196 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/base'
|
2
|
+
|
3
|
+
describe Rush::Connection::Local do
|
4
|
+
before do
|
5
|
+
@sandbox_dir = "/tmp/rush_spec.#{Process.pid}"
|
6
|
+
system "rm -rf #{@sandbox_dir}; mkdir -p #{@sandbox_dir}"
|
7
|
+
|
8
|
+
@con = Rush::Connection::Local.new
|
9
|
+
end
|
10
|
+
|
11
|
+
after do
|
12
|
+
system "rm -rf #{@sandbox_dir}"
|
13
|
+
end
|
14
|
+
|
15
|
+
it "receive -> write_file(file, contents)" do
|
16
|
+
@con.should_receive(:write_file).with('file', 'contents')
|
17
|
+
@con.receive(:action => 'write_file', :full_path => 'file', :payload => 'contents')
|
18
|
+
end
|
19
|
+
|
20
|
+
it "receive -> file_contents(file)" do
|
21
|
+
@con.should_receive(:file_contents).with('file').and_return('the contents')
|
22
|
+
@con.receive(:action => 'file_contents', :full_path => 'file').should == 'the contents'
|
23
|
+
end
|
24
|
+
|
25
|
+
it "receive -> destroy(file or dir)" do
|
26
|
+
@con.should_receive(:destroy).with('file')
|
27
|
+
@con.receive(:action => 'destroy', :full_path => 'file')
|
28
|
+
end
|
29
|
+
|
30
|
+
it "receive -> create_dir(path)" do
|
31
|
+
@con.should_receive(:create_dir).with('dir')
|
32
|
+
@con.receive(:action => 'create_dir', :full_path => 'dir')
|
33
|
+
end
|
34
|
+
|
35
|
+
it "receive -> rename(path, name, new_name)" do
|
36
|
+
@con.should_receive(:rename).with('path', 'name', 'new_name')
|
37
|
+
@con.receive(:action => 'rename', :path => 'path', :name => 'name', :new_name => 'new_name')
|
38
|
+
end
|
39
|
+
|
40
|
+
it "receive -> copy(src, dst)" do
|
41
|
+
@con.should_receive(:copy).with('src', 'dst')
|
42
|
+
@con.receive(:action => 'copy', :src => 'src', :dst => 'dst')
|
43
|
+
end
|
44
|
+
|
45
|
+
it "receive -> read_archive(full_path)" do
|
46
|
+
@con.should_receive(:read_archive).with('full_path').and_return('archive data')
|
47
|
+
@con.receive(:action => 'read_archive', :full_path => 'full_path').should == 'archive data'
|
48
|
+
end
|
49
|
+
|
50
|
+
it "receive -> write_archive(archive, dir)" do
|
51
|
+
@con.should_receive(:write_archive).with('archive', 'dir')
|
52
|
+
@con.receive(:action => 'write_archive', :dir => 'dir', :payload => 'archive')
|
53
|
+
end
|
54
|
+
|
55
|
+
it "receive -> index(base_path, glob)" do
|
56
|
+
@con.should_receive(:index).with('base_path', '*').and_return(%w(1 2))
|
57
|
+
@con.receive(:action => 'index', :base_path => 'base_path', :glob => '*').should == "1\n2\n"
|
58
|
+
end
|
59
|
+
|
60
|
+
it "receive -> stat(full_path)" do
|
61
|
+
@con.should_receive(:stat).with('full_path').and_return(1 => 2)
|
62
|
+
@con.receive(:action => 'stat', :full_path => 'full_path').should == YAML.dump(1 => 2)
|
63
|
+
end
|
64
|
+
|
65
|
+
it "receive -> size(full_path)" do
|
66
|
+
@con.should_receive(:size).with('full_path').and_return("1024")
|
67
|
+
@con.receive(:action => 'size', :full_path => 'full_path').should == "1024"
|
68
|
+
end
|
69
|
+
|
70
|
+
it "receive -> processes" do
|
71
|
+
@con.should_receive(:processes).with().and_return([ { :pid => 1 } ])
|
72
|
+
@con.receive(:action => 'processes').should == YAML.dump([ { :pid => 1 } ])
|
73
|
+
end
|
74
|
+
|
75
|
+
it "receive -> process_alive" do
|
76
|
+
@con.should_receive(:process_alive).with(123).and_return(true)
|
77
|
+
@con.receive(:action => 'process_alive', :pid => 123).should == '1'
|
78
|
+
end
|
79
|
+
|
80
|
+
it "receive -> kill_process" do
|
81
|
+
@con.should_receive(:kill_process).with(123).and_return(true)
|
82
|
+
@con.receive(:action => 'kill_process', :pid => 123)
|
83
|
+
end
|
84
|
+
|
85
|
+
it "receive -> unknown action exception" do
|
86
|
+
lambda { @con.receive(:action => 'does_not_exist') }.should raise_error(Rush::Connection::Local::UnknownAction)
|
87
|
+
end
|
88
|
+
|
89
|
+
it "write_file writes contents to a file" do
|
90
|
+
fname = "#{@sandbox_dir}/a_file"
|
91
|
+
data = "some data"
|
92
|
+
@con.write_file(fname, data)
|
93
|
+
File.read(fname).should == data
|
94
|
+
end
|
95
|
+
|
96
|
+
it "file_contents reads a file's contents" do
|
97
|
+
fname = "#{@sandbox_dir}/a_file"
|
98
|
+
system "echo stuff > #{fname}"
|
99
|
+
@con.file_contents(fname).should == "stuff\n"
|
100
|
+
end
|
101
|
+
|
102
|
+
it "destroy to destroy a file or dir" do
|
103
|
+
fname = "#{@sandbox_dir}/delete_me"
|
104
|
+
system "touch #{fname}"
|
105
|
+
@con.destroy(fname)
|
106
|
+
File.exists?(fname).should be_false
|
107
|
+
end
|
108
|
+
|
109
|
+
it "create_dir creates a directory" do
|
110
|
+
fname = "#{@sandbox_dir}/a/b/c/"
|
111
|
+
@con.create_dir(fname)
|
112
|
+
File.directory?(fname).should be_true
|
113
|
+
end
|
114
|
+
|
115
|
+
it "rename to rename entries within a dir" do
|
116
|
+
system "touch #{@sandbox_dir}/a"
|
117
|
+
@con.rename(@sandbox_dir, 'a', 'b')
|
118
|
+
File.exists?("#{@sandbox_dir}/a").should be_false
|
119
|
+
File.exists?("#{@sandbox_dir}/b").should be_true
|
120
|
+
end
|
121
|
+
|
122
|
+
it "copy to copy an entry to another dir on the same box" do
|
123
|
+
system "mkdir #{@sandbox_dir}/subdir"
|
124
|
+
system "touch #{@sandbox_dir}/a"
|
125
|
+
@con.copy("#{@sandbox_dir}/a", "#{@sandbox_dir}/subdir")
|
126
|
+
File.exists?("#{@sandbox_dir}/a").should be_true
|
127
|
+
File.exists?("#{@sandbox_dir}/subdir/a").should be_true
|
128
|
+
end
|
129
|
+
|
130
|
+
it "read_archive to pull an archive of a dir into a byte stream" do
|
131
|
+
system "touch #{@sandbox_dir}/a"
|
132
|
+
@con.read_archive(@sandbox_dir).size.should > 50
|
133
|
+
end
|
134
|
+
|
135
|
+
it "write_archive to turn a byte stream into a dir" do
|
136
|
+
system "cd #{@sandbox_dir}; mkdir -p a; touch a/b; tar cf xfer.tar a; mkdir dst"
|
137
|
+
archive = File.read("#{@sandbox_dir}/xfer.tar")
|
138
|
+
@con.write_archive(archive, "#{@sandbox_dir}/dst")
|
139
|
+
File.directory?("#{@sandbox_dir}/dst/a").should be_true
|
140
|
+
File.exists?("#{@sandbox_dir}/dst/a/b").should be_true
|
141
|
+
end
|
142
|
+
|
143
|
+
it "index fetches list of all files and dirs in a dir when pattern is empty" do
|
144
|
+
system "cd #{@sandbox_dir}; mkdir dir; touch file"
|
145
|
+
@con.index(@sandbox_dir, '').should == [ 'dir/', 'file' ]
|
146
|
+
end
|
147
|
+
|
148
|
+
it "index fetches only files with a certain extension with a flat pattern, *.rb" do
|
149
|
+
system "cd #{@sandbox_dir}; touch a.rb; touch b.txt"
|
150
|
+
@con.index(@sandbox_dir, '*.rb').should == [ 'a.rb' ]
|
151
|
+
end
|
152
|
+
|
153
|
+
it "stat gives file stats like size and timestamps" do
|
154
|
+
@con.stat(@sandbox_dir).should have_key(:ctime)
|
155
|
+
@con.stat(@sandbox_dir).should have_key(:size)
|
156
|
+
end
|
157
|
+
|
158
|
+
if !RUBY_PLATFORM.match(/darwin/) # doesn't work on OS X 'cause du switches are different
|
159
|
+
it "size gives size of a directory and all its contents recursively" do
|
160
|
+
system "mkdir -p #{@sandbox_dir}/a/b/; echo 1234 > #{@sandbox_dir}/a/b/c"
|
161
|
+
@con.size(@sandbox_dir).should == (4096*3 + 5)
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
165
|
+
it "parses ps output on os x" do
|
166
|
+
@con.parse_ps("21712 501 1236 0 /usr/bin/vi somefile.rb").should == {
|
167
|
+
:pid => "21712",
|
168
|
+
:uid => "501",
|
169
|
+
:rss => "1236",
|
170
|
+
:cpu => "0",
|
171
|
+
:command => '/usr/bin/vi',
|
172
|
+
:cmdline => '/usr/bin/vi somefile.rb',
|
173
|
+
}
|
174
|
+
end
|
175
|
+
|
176
|
+
it "gets the list of processes on os x via the ps command" do
|
177
|
+
@con.should_receive(:os_x_raw_ps).and_return <<EOPS
|
178
|
+
PID UID RSS CPU COMMAND
|
179
|
+
1 0 1111 0 cmd1 args
|
180
|
+
2 501 222 1 cmd2
|
181
|
+
EOPS
|
182
|
+
@con.os_x_processes.should == [
|
183
|
+
{ :pid => "1", :uid => "0", :rss => "1111", :cpu => "0", :command => "cmd1", :cmdline => "cmd1 args" },
|
184
|
+
{ :pid => "2", :uid => "501", :rss => "222", :cpu => "1", :command => "cmd2", :cmdline => "cmd2" },
|
185
|
+
]
|
186
|
+
end
|
187
|
+
|
188
|
+
it "checks whether a given process is alive by pid" do
|
189
|
+
@con.process_alive(Process.pid).should == true
|
190
|
+
end
|
191
|
+
|
192
|
+
it "kills a process by pid" do
|
193
|
+
::Process.should_receive(:kill).with('TERM', 123)
|
194
|
+
@con.kill_process('123')
|
195
|
+
end
|
196
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/base'
|
2
|
+
|
3
|
+
describe Rush::Process do
|
4
|
+
before do
|
5
|
+
@pid = fork do
|
6
|
+
sleep 999
|
7
|
+
end
|
8
|
+
@process = Rush::Process.all.detect { |p| p.pid == @pid }
|
9
|
+
end
|
10
|
+
|
11
|
+
after do
|
12
|
+
system "kill -9 #{@pid}"
|
13
|
+
end
|
14
|
+
|
15
|
+
it "gets the list of all processes" do
|
16
|
+
list = Rush::Process.all
|
17
|
+
list.size.should > 5
|
18
|
+
list.first.should be_kind_of(Rush::Process)
|
19
|
+
end
|
20
|
+
|
21
|
+
it "knows the pid" do
|
22
|
+
@process.pid.should == @pid
|
23
|
+
end
|
24
|
+
|
25
|
+
it "knows the uid" do
|
26
|
+
@process.uid.should == ::Process.uid
|
27
|
+
end
|
28
|
+
|
29
|
+
it "knows the executed binary" do
|
30
|
+
@process.command.should == "ruby"
|
31
|
+
end
|
32
|
+
|
33
|
+
it "knows the command line" do
|
34
|
+
@process.cmdline.should match(/process_spec.rb/)
|
35
|
+
end
|
36
|
+
|
37
|
+
it "can kill itself" do
|
38
|
+
system "sleep 30 &"
|
39
|
+
@process = Rush::Process.all.detect { |p| p.command == "sleep" }
|
40
|
+
@process.kill
|
41
|
+
sleep 0.1
|
42
|
+
@process.alive?.should be_false
|
43
|
+
end
|
44
|
+
end
|
data/spec/remote_spec.rb
ADDED
@@ -0,0 +1,84 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/base'
|
2
|
+
|
3
|
+
describe Rush::Connection::Local do
|
4
|
+
before do
|
5
|
+
@sandbox_dir = "/tmp/rush_spec.#{Process.pid}"
|
6
|
+
system "rm -rf #{@sandbox_dir}; mkdir -p #{@sandbox_dir}"
|
7
|
+
|
8
|
+
@con = Rush::Connection::Remote.new('spec.example.com')
|
9
|
+
end
|
10
|
+
|
11
|
+
after do
|
12
|
+
system "rm -rf #{@sandbox_dir}"
|
13
|
+
end
|
14
|
+
|
15
|
+
it "transmits write_file" do
|
16
|
+
@con.should_receive(:transmit).with(:action => 'write_file', :full_path => 'file', :payload => 'contents')
|
17
|
+
@con.write_file('file', 'contents')
|
18
|
+
end
|
19
|
+
|
20
|
+
it "transmits file_contents" do
|
21
|
+
@con.should_receive(:transmit).with(:action => 'file_contents', :full_path => 'file').and_return('contents')
|
22
|
+
@con.file_contents('file').should == 'contents'
|
23
|
+
end
|
24
|
+
|
25
|
+
it "transmits destroy" do
|
26
|
+
@con.should_receive(:transmit).with(:action => 'destroy', :full_path => 'file')
|
27
|
+
@con.destroy('file')
|
28
|
+
end
|
29
|
+
|
30
|
+
it "transmits create_dir" do
|
31
|
+
@con.should_receive(:transmit).with(:action => 'create_dir', :full_path => 'file')
|
32
|
+
@con.create_dir('file')
|
33
|
+
end
|
34
|
+
|
35
|
+
it "transmits rename" do
|
36
|
+
@con.should_receive(:transmit).with(:action => 'rename', :path => 'path', :name => 'name', :new_name => 'new_name')
|
37
|
+
@con.rename('path', 'name', 'new_name')
|
38
|
+
end
|
39
|
+
|
40
|
+
it "transmits copy" do
|
41
|
+
@con.should_receive(:transmit).with(:action => 'copy', :src => 'src', :dst => 'dst')
|
42
|
+
@con.copy('src', 'dst')
|
43
|
+
end
|
44
|
+
|
45
|
+
it "transmits read_archive" do
|
46
|
+
@con.should_receive(:transmit).with(:action => 'read_archive', :full_path => 'full_path').and_return('archive data')
|
47
|
+
@con.read_archive('full_path').should == 'archive data'
|
48
|
+
end
|
49
|
+
|
50
|
+
it "transmits write_archive" do
|
51
|
+
@con.should_receive(:transmit).with(:action => 'write_archive', :dir => 'dir', :payload => 'archive')
|
52
|
+
@con.write_archive('archive', 'dir')
|
53
|
+
end
|
54
|
+
|
55
|
+
it "transmits index" do
|
56
|
+
@con.should_receive(:transmit).with(:action => 'index', :base_path => 'base_path', :glob => '*').and_return("1\n2\n")
|
57
|
+
@con.index('base_path', '*').should == %w(1 2)
|
58
|
+
end
|
59
|
+
|
60
|
+
it "transmits stat" do
|
61
|
+
@con.should_receive(:transmit).with(:action => 'stat', :full_path => 'full_path').and_return(YAML.dump(1 => 2))
|
62
|
+
@con.stat('full_path').should == { 1 => 2 }
|
63
|
+
end
|
64
|
+
|
65
|
+
it "transmits size" do
|
66
|
+
@con.should_receive(:transmit).with(:action => 'size', :full_path => 'full_path').and_return("")
|
67
|
+
@con.size('full_path')
|
68
|
+
end
|
69
|
+
|
70
|
+
it "transmits processes" do
|
71
|
+
@con.should_receive(:transmit).with(:action => 'processes').and_return(YAML.dump([ { :pid => 1 } ]))
|
72
|
+
@con.processes.should == [ { :pid => 1 } ]
|
73
|
+
end
|
74
|
+
|
75
|
+
it "transmits process_alive" do
|
76
|
+
@con.should_receive(:transmit).with(:action => 'process_alive', :pid => 123).and_return(true)
|
77
|
+
@con.process_alive(123).should == true
|
78
|
+
end
|
79
|
+
|
80
|
+
it "transmits kill_process" do
|
81
|
+
@con.should_receive(:transmit).with(:action => 'kill_process', :pid => 123)
|
82
|
+
@con.kill_process(123)
|
83
|
+
end
|
84
|
+
end
|
@@ -0,0 +1,44 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/base'
|
2
|
+
|
3
|
+
describe Rush::SearchResults do
|
4
|
+
before do
|
5
|
+
@results = Rush::SearchResults.new(/pat/)
|
6
|
+
@file = Rush::File.new("file")
|
7
|
+
end
|
8
|
+
|
9
|
+
it "returns its list of entries" do
|
10
|
+
@results.add(@file, %w(a))
|
11
|
+
@results.entries.should == [ @file ]
|
12
|
+
end
|
13
|
+
|
14
|
+
it "only returns each entry once no matter how many line matches it has" do
|
15
|
+
@results.add(@file, %w(a b))
|
16
|
+
@results.entries.should == [ @file ]
|
17
|
+
end
|
18
|
+
|
19
|
+
it "returns its list of matched lines" do
|
20
|
+
@results.add(@file, %w(a b))
|
21
|
+
@results.lines.should == %w(a b)
|
22
|
+
end
|
23
|
+
|
24
|
+
it "returns all lines for each entry in a flattened form" do
|
25
|
+
file2 = Rush::File.new("another file")
|
26
|
+
@results.add(@file, %w(a b))
|
27
|
+
@results.add(file2, %w(c d))
|
28
|
+
@results.lines.should == %w(a b c d)
|
29
|
+
end
|
30
|
+
|
31
|
+
it "returns a hash of entries_with_lines" do
|
32
|
+
@results.add(@file, %w(a))
|
33
|
+
@results.entries_with_lines.should == { @file => %w(a) }
|
34
|
+
end
|
35
|
+
|
36
|
+
it "mixes in Commands to operate like a dir or entry array" do
|
37
|
+
@results.methods.include?("search").should be_true
|
38
|
+
end
|
39
|
+
|
40
|
+
it "mixes in Enumerable to behave like an array" do
|
41
|
+
@results.add(@file, %w(a))
|
42
|
+
@results.map { |e| e }.should == [ @file ]
|
43
|
+
end
|
44
|
+
end
|