recls-ruby 2.6.4
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.
- checksums.yaml +7 -0
- data/LICENSE +31 -0
- data/README.md +2 -0
- data/examples/show_hidden_files.rb +15 -0
- data/examples/show_readonly_files.rb +14 -0
- data/lib/recls.rb +41 -0
- data/lib/recls/entry.rb +328 -0
- data/lib/recls/filesearch.rb +251 -0
- data/lib/recls/flags.rb +77 -0
- data/lib/recls/foreach.rb +103 -0
- data/lib/recls/recls.rb +113 -0
- data/lib/recls/stat.rb +104 -0
- data/lib/recls/util.rb +73 -0
- data/lib/recls/version.rb +53 -0
- data/lib/recls/ximpl/os.rb +85 -0
- data/lib/recls/ximpl/unix.rb +81 -0
- data/lib/recls/ximpl/util.rb +650 -0
- data/lib/recls/ximpl/windows.rb +197 -0
- data/test/scratch/test_display_parts.rb +40 -0
- data/test/scratch/test_entry.rb +81 -0
- data/test/scratch/test_foreach.rb +41 -0
- data/test/scratch/test_show_dev_and_ino.rb +13 -0
- data/test/scratch/test_show_hidden.rb +30 -0
- data/test/unit/tc_recls_entries.rb +55 -0
- data/test/unit/tc_recls_entry.rb +40 -0
- data/test/unit/tc_recls_file_search.rb +68 -0
- data/test/unit/tc_recls_module.rb +78 -0
- data/test/unit/tc_recls_util.rb +159 -0
- data/test/unit/tc_recls_ximpl_util.rb +908 -0
- data/test/unit/ts_all.rb +20 -0
- metadata +73 -0
@@ -0,0 +1,197 @@
|
|
1
|
+
# ######################################################################### #
|
2
|
+
# File: recls/ximpl/windows.rb
|
3
|
+
#
|
4
|
+
# Purpose: Windows-specific constructs for the recls library.
|
5
|
+
#
|
6
|
+
# Created: 19th February 2014
|
7
|
+
# Updated: 29th December 2015
|
8
|
+
#
|
9
|
+
# Author: Matthew Wilson
|
10
|
+
#
|
11
|
+
# Copyright (c) 2012-2015, Matthew Wilson and Synesis Software
|
12
|
+
# All rights reserved.
|
13
|
+
#
|
14
|
+
# Redistribution and use in source and binary forms, with or without
|
15
|
+
# modification, are permitted provided that the following conditions are met:
|
16
|
+
#
|
17
|
+
# * Redistributions of source code must retain the above copyright notice,
|
18
|
+
# this list of conditions and the following disclaimer.
|
19
|
+
#
|
20
|
+
# * Redistributions in binary form must reproduce the above copyright notice,
|
21
|
+
# this list of conditions and the following disclaimer in the documentation
|
22
|
+
# and/or other materials provided with the distribution.
|
23
|
+
#
|
24
|
+
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
25
|
+
# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
26
|
+
# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
27
|
+
# ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
28
|
+
# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
29
|
+
# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
30
|
+
# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
31
|
+
# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
32
|
+
# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
33
|
+
# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
34
|
+
# POSSIBILITY OF SUCH DAMAGE.
|
35
|
+
#
|
36
|
+
# ######################################################################### #
|
37
|
+
|
38
|
+
|
39
|
+
require 'Win32API'
|
40
|
+
|
41
|
+
module Recls
|
42
|
+
|
43
|
+
module Ximpl
|
44
|
+
|
45
|
+
class FileStat < File::Stat
|
46
|
+
|
47
|
+
private
|
48
|
+
GetFileAttributes = Win32API.new('kernel32', 'GetFileAttributes', [ 'P' ], 'I')
|
49
|
+
GetFileInformationByHandle = Win32API.new('kernel32', 'GetFileInformationByHandle', [ 'L', 'P' ], 'I')
|
50
|
+
GetShortPathName = Win32API.new('kernel32', 'GetShortPathName', [ 'P', 'P', 'L' ], 'L')
|
51
|
+
CreateFile = Win32API.new('kernel32', 'CreateFile', [ 'P', 'L', 'L', 'L', 'L', 'L', 'L' ], 'L')
|
52
|
+
CloseHandle = Win32API.new('kernel32', 'CloseHandle', [ 'L' ], 'L')
|
53
|
+
FILE_ATTRIBUTE_READONLY = 0x00000001
|
54
|
+
FILE_ATTRIBUTE_HIDDEN = 0x00000002
|
55
|
+
FILE_ATTRIBUTE_SYSTEM = 0x00000004
|
56
|
+
FILE_ATTRIBUTE_DIRECTORY = 0x00000010
|
57
|
+
FILE_ATTRIBUTE_ARCHIVE = 0x00000020
|
58
|
+
FILE_ATTRIBUTE_DEVICE = 0x00000040
|
59
|
+
FILE_ATTRIBUTE_NORMAL = 0x00000080
|
60
|
+
FILE_ATTRIBUTE_TEMPORARY = 0x00000100
|
61
|
+
FILE_ATTRIBUTE_COMPRESSED = 0x00000800
|
62
|
+
FILE_ATTRIBUTE_ENCRYPTED = 0x00004000
|
63
|
+
|
64
|
+
OPEN_EXISTING = 0x00000003
|
65
|
+
FILE_FLAG_OVERLAPPED = 0x40000000
|
66
|
+
NULL = 0x00000000
|
67
|
+
INVALID_HANDLE_VALUE = 0xFFFFFFFF
|
68
|
+
|
69
|
+
MAX_PATH = 260
|
70
|
+
|
71
|
+
BHFI_pack_string = 'LQQQLLLLLL'
|
72
|
+
|
73
|
+
class ByHandleInformation
|
74
|
+
|
75
|
+
def initialize(path)
|
76
|
+
|
77
|
+
@volume_id = 0
|
78
|
+
@file_index = 0
|
79
|
+
@num_links = 0
|
80
|
+
|
81
|
+
# for some reason not forcing this new string causes 'can't modify frozen string (TypeError)' (in Ruby 1.8.x)
|
82
|
+
hFile = CreateFile.call("#{path}", 0, 0, NULL, OPEN_EXISTING, 0, NULL);
|
83
|
+
if INVALID_HANDLE_VALUE != hFile
|
84
|
+
|
85
|
+
begin
|
86
|
+
bhfi = [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ]
|
87
|
+
bhfi = bhfi.pack(BHFI_pack_string)
|
88
|
+
|
89
|
+
if GetFileInformationByHandle.call(hFile, bhfi)
|
90
|
+
|
91
|
+
bhfi = bhfi.unpack(BHFI_pack_string)
|
92
|
+
|
93
|
+
@volume_id = bhfi[4]
|
94
|
+
@file_index = (bhfi[8] << 32) | bhfi[9]
|
95
|
+
@num_links = bhfi[7]
|
96
|
+
else
|
97
|
+
end
|
98
|
+
ensure
|
99
|
+
CloseHandle.call(hFile)
|
100
|
+
end
|
101
|
+
end
|
102
|
+
end
|
103
|
+
|
104
|
+
attr_reader :volume_id
|
105
|
+
attr_reader :file_index
|
106
|
+
attr_reader :num_links
|
107
|
+
end
|
108
|
+
|
109
|
+
private
|
110
|
+
def has_attribute_? (attr)
|
111
|
+
|
112
|
+
0 != (attr & @attributes)
|
113
|
+
end
|
114
|
+
|
115
|
+
private
|
116
|
+
def initialize(path)
|
117
|
+
|
118
|
+
@path = path
|
119
|
+
|
120
|
+
# for some reason not forcing this new string causes 'can't modify frozen string (TypeError)'
|
121
|
+
attributes = GetFileAttributes.call("#{path}")
|
122
|
+
|
123
|
+
if 0xffffffff == attributes
|
124
|
+
@attributes = 0
|
125
|
+
else
|
126
|
+
@attributes = attributes
|
127
|
+
end
|
128
|
+
|
129
|
+
super(path)
|
130
|
+
|
131
|
+
@by_handle_information = ByHandleInformation.new(path)
|
132
|
+
|
133
|
+
buff = ' ' * MAX_PATH
|
134
|
+
n = GetShortPathName.call(path, buff, buff.length)
|
135
|
+
@short_path = (0 == n) ? nil : buff[0...n]
|
136
|
+
end
|
137
|
+
|
138
|
+
public
|
139
|
+
attr_reader :attributes
|
140
|
+
attr_reader :path
|
141
|
+
attr_reader :by_handle_information
|
142
|
+
attr_reader :short_path
|
143
|
+
|
144
|
+
def hidden?
|
145
|
+
|
146
|
+
0 != (FILE_ATTRIBUTE_HIDDEN & @attributes)
|
147
|
+
end
|
148
|
+
|
149
|
+
# Windows-specific attributes
|
150
|
+
|
151
|
+
def system?
|
152
|
+
|
153
|
+
has_attribute_? FILE_ATTRIBUTE_SYSTEM
|
154
|
+
end
|
155
|
+
|
156
|
+
def archive?
|
157
|
+
|
158
|
+
has_attribute_? FILE_ATTRIBUTE_ARCHIVE
|
159
|
+
end
|
160
|
+
|
161
|
+
def device?
|
162
|
+
|
163
|
+
has_attribute_? FILE_ATTRIBUTE_DEVICE
|
164
|
+
end
|
165
|
+
|
166
|
+
def normal?
|
167
|
+
|
168
|
+
has_attribute_? FILE_ATTRIBUTE_NORMAL
|
169
|
+
end
|
170
|
+
|
171
|
+
def temporary?
|
172
|
+
|
173
|
+
has_attribute_? FILE_ATTRIBUTE_TEMPORARY
|
174
|
+
end
|
175
|
+
|
176
|
+
def compressed?
|
177
|
+
|
178
|
+
has_attribute_? FILE_ATTRIBUTE_COMPRESSED
|
179
|
+
end
|
180
|
+
|
181
|
+
def encrypted?
|
182
|
+
|
183
|
+
has_attribute_? FILE_ATTRIBUTE_ENCRYPTED
|
184
|
+
end
|
185
|
+
|
186
|
+
|
187
|
+
public
|
188
|
+
def FileStat.stat(path)
|
189
|
+
|
190
|
+
Recls::Ximpl::FileStat.new(path)
|
191
|
+
end
|
192
|
+
end
|
193
|
+
end
|
194
|
+
end
|
195
|
+
|
196
|
+
# ############################## end of file ############################# #
|
197
|
+
|
@@ -0,0 +1,40 @@
|
|
1
|
+
#! /usr/bin/ruby
|
2
|
+
#
|
3
|
+
# test Recls entry methods
|
4
|
+
|
5
|
+
$:.unshift File.join(File.dirname(__FILE__), '../..', 'lib')
|
6
|
+
|
7
|
+
require 'recls'
|
8
|
+
|
9
|
+
Recls::FileSearch.new(nil, nil, Recls::FILES | Recls::RECURSIVE).each do |fe|
|
10
|
+
|
11
|
+
puts
|
12
|
+
puts fe.path
|
13
|
+
puts fe.short_path
|
14
|
+
puts fe.directory_path
|
15
|
+
puts fe.drive
|
16
|
+
puts "".ljust(fe.drive.size) + fe.directory
|
17
|
+
puts "".ljust(fe.directory_path.size) + fe.file
|
18
|
+
puts "".ljust(fe.directory_path.size) + fe.file_short_name
|
19
|
+
puts "".ljust(fe.directory_path.size) + fe.stem
|
20
|
+
puts "".ljust(fe.directory_path.size + fe.stem.size) + fe.extension
|
21
|
+
n = fe.drive.size
|
22
|
+
fe.directory_parts.each do |part|
|
23
|
+
|
24
|
+
puts "".ljust(n) + part
|
25
|
+
n += part.size
|
26
|
+
end
|
27
|
+
|
28
|
+
puts fe.search_directory
|
29
|
+
puts "".ljust(fe.search_directory.size) + fe.search_relative_path
|
30
|
+
puts "".ljust(fe.search_directory.size) + fe.search_relative_directory_path
|
31
|
+
puts "".ljust(fe.search_directory.size) + fe.search_relative_directory
|
32
|
+
|
33
|
+
n = fe.search_directory.size
|
34
|
+
fe.search_relative_directory_parts.each do |part|
|
35
|
+
|
36
|
+
puts "".ljust(n) + part
|
37
|
+
n += part.size
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
@@ -0,0 +1,81 @@
|
|
1
|
+
#! /usr/bin/ruby
|
2
|
+
#
|
3
|
+
# test Recls entry methods
|
4
|
+
|
5
|
+
$:.unshift File.join(File.dirname(__FILE__), '../..', 'lib')
|
6
|
+
|
7
|
+
require 'recls'
|
8
|
+
|
9
|
+
puts "PATH_NAME_SEPARATOR:\t[#{Recls::PATH_NAME_SEPARATOR}]"
|
10
|
+
puts "PATH_SEPARATOR:\t[#{Recls::PATH_SEPARATOR}]"
|
11
|
+
puts "WILDCARDS_ALL:\t[#{Recls::WILDCARDS_ALL}]"
|
12
|
+
|
13
|
+
def show_entry f
|
14
|
+
|
15
|
+
puts "entry:"
|
16
|
+
puts "\t#{'(entry)'.ljust(20)}\t#{f}"
|
17
|
+
puts "\t#{'f.path'.ljust(20)}\t#{f.path}"
|
18
|
+
puts "\t#{'f.drive'.ljust(20)}\t#{f.drive}"
|
19
|
+
puts "\t#{'f.directory_path'.ljust(20)}\t#{f.directory_path}"
|
20
|
+
puts "\t#{'f.directory'.ljust(20)}\t#{f.directory}"
|
21
|
+
directory_parts = f.directory_parts
|
22
|
+
puts "\t#{'f.directory_parts'.ljust(20)}\t[#{directory_parts.size}]"
|
23
|
+
directory_parts.each do |part|
|
24
|
+
puts "\t#{''.ljust(20)}\t\t#{part}"
|
25
|
+
end
|
26
|
+
search_relative_directory_parts = f.search_relative_directory_parts
|
27
|
+
puts "\t#{'f.search_relative_directory_parts'.ljust(20)}\t[#{search_relative_directory_parts.size}]"
|
28
|
+
search_relative_directory_parts.each do |part|
|
29
|
+
puts "\t#{''.ljust(20)}\t\t#{part}"
|
30
|
+
end
|
31
|
+
puts "\t#{'f.file_full_name'.ljust(20)}\t#{f.file_full_name}"
|
32
|
+
puts "\t#{'f.file_short_name'.ljust(20)}\t#{f.file_short_name}"
|
33
|
+
puts "\t#{'f.file_name_only'.ljust(20)}\t#{f.file_name_only}"
|
34
|
+
puts "\t#{'f.stem'.ljust(20)}\t#{f.stem}"
|
35
|
+
puts "\t#{'f.file_extension'.ljust(20)}\t#{f.file_extension}"
|
36
|
+
puts "\t#{'f.search_directory'.ljust(20)}\t#{f.search_directory}"
|
37
|
+
puts "\t#{'f.search_relative_path'.ljust(20)}\t#{f.search_relative_path}"
|
38
|
+
puts "\t#{'f.search_relative_directory'.ljust(20)}\t#{f.search_relative_directory}"
|
39
|
+
puts "\t#{'f.search_relative_directory_path'.ljust(20)}\t#{f.search_relative_directory_path}"
|
40
|
+
|
41
|
+
puts "\t#{'f.size'.ljust(20)}\t#{f.size}"
|
42
|
+
|
43
|
+
puts "\t#{'f.exist?'.ljust(20)}\t#{f.exist?}"
|
44
|
+
puts "\t#{'f.hidden?'.ljust(20)}\t#{f.hidden?}"
|
45
|
+
puts "\t#{'f.readonly?'.ljust(20)}\t#{f.readonly?}"
|
46
|
+
puts "\t#{'f.directory?'.ljust(20)}\t#{f.directory?}"
|
47
|
+
puts "\t#{'f.file?'.ljust(20)}\t#{f.file?}"
|
48
|
+
puts "\t#{'f.socket?'.ljust(20)}\t#{f.socket?}"
|
49
|
+
|
50
|
+
puts "\t#{'f.modification_time'.ljust(20)}\t#{f.modification_time}"
|
51
|
+
puts "\t#{'f.last_access_time'.ljust(20)}\t#{f.last_access_time}"
|
52
|
+
end
|
53
|
+
|
54
|
+
puts
|
55
|
+
puts "stat of '.':"
|
56
|
+
show_entry Recls::stat '.'
|
57
|
+
|
58
|
+
puts
|
59
|
+
puts "stat of '~':"
|
60
|
+
show_entry Recls::stat '~'
|
61
|
+
|
62
|
+
puts
|
63
|
+
puts "directories:"
|
64
|
+
num_directories = 0
|
65
|
+
Recls::FileSearch.new('.', '*', Recls::DIRECTORIES).each do |fe|
|
66
|
+
|
67
|
+
num_directories += 1
|
68
|
+
puts "\t[#{fe.search_relative_path}]"
|
69
|
+
end
|
70
|
+
puts " #{num_directories} directories"
|
71
|
+
|
72
|
+
puts
|
73
|
+
puts "files:"
|
74
|
+
num_files = 0
|
75
|
+
Recls::FileSearch.new('.', '*.rb', Recls::RECURSIVE | Recls::FILES).each do |fe|
|
76
|
+
|
77
|
+
num_files += 1
|
78
|
+
puts "\t<#{fe.search_relative_path}>"
|
79
|
+
end
|
80
|
+
puts " #{num_files} file(s)"
|
81
|
+
|
@@ -0,0 +1,41 @@
|
|
1
|
+
#! /usr/bin/ruby
|
2
|
+
#
|
3
|
+
# test Recls search methods
|
4
|
+
|
5
|
+
$:.unshift File.join(File.dirname(__FILE__), '../..', 'lib')
|
6
|
+
|
7
|
+
|
8
|
+
#require 'recls/util'
|
9
|
+
require 'recls/foreach'
|
10
|
+
#require 'recls'
|
11
|
+
|
12
|
+
puts
|
13
|
+
puts "with given block:"
|
14
|
+
count_1 = 0
|
15
|
+
Recls.foreach(Recls::FileSearch.new(nil, '*.rb', Recls::RECURSIVE)).each do |line, line_number, fe|
|
16
|
+
|
17
|
+
line = line.chomp
|
18
|
+
line_number = 1 + line_number
|
19
|
+
|
20
|
+
puts "#{fe.search_relative_path}(#{line_number + 1}): #{line}"
|
21
|
+
|
22
|
+
count_1 += 1
|
23
|
+
break if 20 == count_1
|
24
|
+
end
|
25
|
+
|
26
|
+
puts
|
27
|
+
puts "as returned enumerator:"
|
28
|
+
e = Recls.foreach(Recls::FileSearch.new(nil, '*.rb', Recls::RECURSIVE))
|
29
|
+
count_2 = 0
|
30
|
+
e.each do |line, line_number, fe|
|
31
|
+
|
32
|
+
line = line.chomp
|
33
|
+
line_number = 1 + line_number
|
34
|
+
|
35
|
+
puts "#{fe.search_relative_path}(#{line_number + 1}): #{line}"
|
36
|
+
|
37
|
+
count_2 += 1
|
38
|
+
break if 20 == count_2
|
39
|
+
end
|
40
|
+
|
41
|
+
|
@@ -0,0 +1,13 @@
|
|
1
|
+
#!/usr/bin/ruby
|
2
|
+
#
|
3
|
+
# Demonstrates use of dev and ino attributes
|
4
|
+
|
5
|
+
$:.unshift File.join(File.dirname(__FILE__), '../..', 'lib')
|
6
|
+
|
7
|
+
require 'recls'
|
8
|
+
|
9
|
+
Recls::FileSearch.new('.', Recls::WILDCARDS_ALL, Recls::FILES | Recls::RECURSIVE).each do |fe|
|
10
|
+
|
11
|
+
puts "#{fe.search_relative_path}\t#{fe.dev}\t#{fe.ino}\t#{fe.nlink}"
|
12
|
+
end
|
13
|
+
|
@@ -0,0 +1,30 @@
|
|
1
|
+
#! /usr/bin/ruby
|
2
|
+
#
|
3
|
+
# Demonstrates search of hidden files
|
4
|
+
|
5
|
+
$:.unshift File.join(File.dirname(__FILE__), '../..', 'lib')
|
6
|
+
|
7
|
+
require 'recls'
|
8
|
+
|
9
|
+
puts
|
10
|
+
puts "Hidden directories:"
|
11
|
+
Recls::FileSearch.new(nil, nil, Recls::RECURSIVE | Recls::DIRECTORIES | Recls::SHOW_HIDDEN).each do |fe|
|
12
|
+
|
13
|
+
puts "\t#{fe.search_relative_path}" if fe.hidden?
|
14
|
+
end
|
15
|
+
|
16
|
+
puts
|
17
|
+
puts "Hidden files:"
|
18
|
+
Recls::FileSearch.new(nil, nil, Recls::RECURSIVE | Recls::FILES | Recls::SHOW_HIDDEN).each do |fe|
|
19
|
+
|
20
|
+
puts "\t#{fe.search_relative_path}" if fe.hidden?
|
21
|
+
end
|
22
|
+
|
23
|
+
|
24
|
+
puts
|
25
|
+
puts "Hidden directories & files:"
|
26
|
+
Recls::FileSearch.new(nil, nil, Recls::RECURSIVE | Recls::DIRECTORIES | Recls::FILES | Recls::MARK_DIRECTORIES | Recls::SHOW_HIDDEN).each do |fe|
|
27
|
+
|
28
|
+
puts "\t#{fe.search_relative_path}" if fe.hidden?
|
29
|
+
end
|
30
|
+
|
@@ -0,0 +1,55 @@
|
|
1
|
+
#!/usr/bin/ruby
|
2
|
+
#
|
3
|
+
# test Recls entries
|
4
|
+
|
5
|
+
$:.unshift File.join(File.dirname(__FILE__), '../..', 'lib')
|
6
|
+
|
7
|
+
|
8
|
+
require 'recls'
|
9
|
+
|
10
|
+
require 'test/unit'
|
11
|
+
|
12
|
+
class Test_Recls_entries < Test::Unit::TestCase
|
13
|
+
|
14
|
+
unless defined? assert_false
|
15
|
+
def assert_false arg0, *args
|
16
|
+
assert !arg0, *args
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
def test_entries_in_directory_have_unique_names
|
21
|
+
|
22
|
+
entries = Recls::FileSearch.new('~', Recls::WILDCARDS_ALL, Recls::FILES).to_a
|
23
|
+
|
24
|
+
hashed_entries = Hash[entries.each_with_index.map { |fe, index| [ fe, index] }]
|
25
|
+
|
26
|
+
# ensure that no duplicates in hash (and hence Entry.hash and Entry.<=> work)
|
27
|
+
assert_equal entries.size, hashed_entries.size
|
28
|
+
|
29
|
+
entries.each_with_index do |entry, index|
|
30
|
+
|
31
|
+
entry_a = entries[index]
|
32
|
+
entry_b = Recls.stat(entries[index].path)
|
33
|
+
|
34
|
+
# ensure that different entry instances representing the same path evaluate
|
35
|
+
# equal (and hence Entry.eq? and Entry.== work)
|
36
|
+
|
37
|
+
assert entry_a.eql? entry_a
|
38
|
+
assert entry_a.eql? entry_b
|
39
|
+
assert_false entry_a.eql? entry_a.path
|
40
|
+
assert_false entry_a.eql? entry_b.path
|
41
|
+
|
42
|
+
assert_equal entry_a, entry_a
|
43
|
+
assert_equal entry_a, entry_b
|
44
|
+
assert_equal entry_a, entry_a.path
|
45
|
+
assert_equal entry_a, entry_b.path
|
46
|
+
|
47
|
+
assert_same entry_a, entries[index]
|
48
|
+
assert_not_same entry_a, entry_b
|
49
|
+
|
50
|
+
assert_equal index, hashed_entries[entry_a]
|
51
|
+
assert_equal index, hashed_entries[entry_b]
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|