win32-file-stat 1.2.3

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/CHANGES ADDED
@@ -0,0 +1,32 @@
1
+ == 1.2.3 - 4-Nov-2006
2
+ * Bug fix for file sizes over 4gb.
3
+
4
+ == 1.2.2 - 13-May-2006
5
+ * Yet another blksize bug fix.
6
+ * Minor tweak to the pretty_print method with regards to handling nil values.
7
+ * Bumped the minimum required windows-pr version to 0.4.0 in the gemspec.
8
+
9
+ == 1.2.1 - 12-May-2006
10
+ * Fixed a bug with regards to the block count where the constructor would die
11
+ with a FloatDomainError if the blksize returned 0 or nil. It now defaults
12
+ to nil in that event.
13
+
14
+ == 1.2.0 - 23-Apr-2006
15
+ * Removed the attribute setters. From now on this class provides readonly
16
+ methods. Use the win32-file package for attribute setters.
17
+ * Added the content_indexed? alias for the indexed? method.
18
+ * Corresponding test suite changes.
19
+ * Fixed the pp issue by writing a custom pretty_print method.
20
+
21
+ == 1.1.0 - 15-Apr-2006
22
+ * Added the chardev?, dev_major, dev_minor directory?, file?, executable?,
23
+ executable_real?, ftype, grpowned?, owned?, pipe?, readable?, readable_real?,
24
+ rdev_major, rdev_minor, setgid?, setuid?, size?, socket?, sticky?, symlink?,
25
+ writable?, writable_real? and zero? methods. Note that not all of these
26
+ methods return meaningful values and were merely added to match the current
27
+ spec. See documentation for details.
28
+ * Added a VERSION constant.
29
+ * Some optimization in the constructor.
30
+
31
+ == 1.0.0 - 13-Apr-2006
32
+ * Initial release
data/MANIFEST ADDED
@@ -0,0 +1,11 @@
1
+ CHANGES
2
+ README
3
+ MANIFEST
4
+ install.rb
5
+ win32-file-stat.gemspec
6
+
7
+ lib/win32/file/stat.rb
8
+
9
+ test/sometestfile.exe
10
+ test/sometestfile.txt
11
+ test/tc_file_stat.rb
data/README ADDED
@@ -0,0 +1,64 @@
1
+ = Description
2
+ A redefinition of the File::Stat class for MS Windows.
3
+
4
+ = Prerequisites
5
+ Ruby 1.8.0 or later.
6
+ windows-pr 0.4.0 or later.
7
+
8
+ = Installation, pure Ruby
9
+ == Manual Installation
10
+ ruby test/tc_file_stat.rb (optional)
11
+ ruby install.rb
12
+
13
+ == Gem Installation
14
+ === Local
15
+ ruby test/tc_file_stat.rb (Unix, optional)
16
+ gem install win32-file-stat-<version>.gem
17
+ === Remote
18
+ gem install win32-file-stat
19
+
20
+ = Synopsis
21
+ require 'win32/file/stat'
22
+
23
+ stat = File::Stat.new('file.txt')
24
+ stat.size
25
+ stat.readonly?
26
+ stat.hidden?
27
+
28
+ = Differences between Ruby's File::Stat and this version:
29
+ * The File::Stat#blksize method returns a meaningful value.
30
+ * The File::Stat#blockdev method works more accurately.
31
+ * The File::Stat#blocks method returns a meaningful value.
32
+ * The File::Stat#dev method returns a drive letter, not a number.
33
+ * The File::Stat#executable? method works properly.
34
+ * The File::Stat#executable_real? returns the same value as
35
+ File::Stat#executable? (which now works properly).
36
+ * The File::Stat#file? method works properly.
37
+ * The File::Stat#ftype method works more accurately.
38
+ * The File::Stat#pipe method works properly.
39
+ * The File::Stat#size method handles file sizes greater than 2 gigabytes
40
+ correctly.
41
+ * The File::Stat#socket method works more accurately.
42
+ * Allows you to get file attributes specific to MS Windows, e.g. archive,
43
+ hidden, etc.
44
+ * The pp (pretty print) output has been customized.
45
+
46
+ = Known issues or bugs
47
+ None that I'm aware of. Please report any bugs you find on the project page
48
+ at http://www.rubyforge.org/projects/win32utils.
49
+
50
+ = Miscellaneous
51
+ I had to require 'pp' explicitly in order to deal with the fact that pp.rb
52
+ has a builtin pretty_print method for File::Stat. If I didn't do this
53
+ you would end up using the pretty_print in pp.rb, which would break.
54
+
55
+ = License
56
+ Ruby's
57
+
58
+ = Warranty
59
+ This package is provided "as is" and without any express or
60
+ implied warranties, including, without limitation, the implied
61
+ warranties of merchantability and fitness for a particular purpose.
62
+
63
+ = Author
64
+ Daniel J. Berger
data/install.rb ADDED
@@ -0,0 +1,12 @@
1
+ require 'rbconfig'
2
+ require 'ftools'
3
+ include Config
4
+
5
+ sitelibdir = CONFIG['sitelibdir']
6
+ installdir = sitelibdir + '/win32/file'
7
+ basedir = File.dirname(installdir)
8
+ file = 'lib\win32\file\stat.rb'
9
+
10
+ Dir.mkdir(basedir) unless File.exists?(basedir)
11
+ Dir.mkdir(installdir) unless File.exists?(installdir)
12
+ File.copy(file, installdir, true)
@@ -0,0 +1,552 @@
1
+ require 'windows/msvcrt/buffer'
2
+ require 'windows/msvcrt/file'
3
+ require 'windows/filesystem'
4
+ require 'windows/device_io'
5
+ require 'windows/path'
6
+ require 'windows/file'
7
+ require 'windows/error'
8
+ require 'windows/handle'
9
+ require 'pp'
10
+
11
+ class File::Stat
12
+ include Windows::MSVCRT::Buffer
13
+ include Windows::MSVCRT::File
14
+ include Windows::DeviceIO
15
+ include Windows::FileSystem
16
+ include Windows::Path
17
+ include Windows::File
18
+ include Windows::Error
19
+ include Windows::Handle
20
+ include Comparable
21
+
22
+ VERSION = '1.2.3'
23
+
24
+ # Defined in Ruby's win32.h. Not meant for public consumption.
25
+ S_IWGRP = 0020
26
+ S_IWOTH = 0002
27
+
28
+ attr_reader :dev_major, :dev_minor, :rdev_major, :rdev_minor
29
+
30
+ # Creates and returns a File::Stat object, which encapsulate common status
31
+ # information for File objects on MS Windows sytems. The information is
32
+ # recorded at the moment the File::Stat object is created; changes made to
33
+ # the file after that point will not be reflected.
34
+ #
35
+ def initialize(file)
36
+ @file = file
37
+
38
+ @blockdev = false
39
+ @file_type = get_file_type(file) # May update @blockdev
40
+
41
+ @chardev = @file_type == FILE_TYPE_CHAR
42
+
43
+ stat_buf = [0,0,0,0,0,0,0,0,0,0,0,0,0].pack('ISSssssIIQQQQ')
44
+
45
+ # The stat64 function doesn't seem to like character devices
46
+ if stat64(file, stat_buf) != 0
47
+ raise ArgumentError, get_last_error unless @chardev
48
+ end
49
+
50
+ # Some bytes skipped (padding for struct alignment)
51
+ @dev = stat_buf[0, 4].unpack('I').first # Drive number
52
+ @ino = stat_buf[4, 2].unpack('S').first # Meaningless
53
+ @mode = stat_buf[6, 2].unpack('S').first # File mode bit mask
54
+ @nlink = stat_buf[8, 2].unpack('s').first # Always 1
55
+ @uid = stat_buf[10, 2].unpack('s').first # Always 0
56
+ @gid = stat_buf[12, 2].unpack('s').first # Always 0
57
+ @rdev = stat_buf[16, 4].unpack('I').first # Same as dev
58
+ @size = stat_buf[24, 8].unpack('Q').first # Size of file in bytes
59
+ @atime = Time.at(stat_buf[32, 8].unpack('Q').first) # Access time
60
+ @mtime = Time.at(stat_buf[40, 8].unpack('Q').first) # Modification time
61
+ @ctime = Time.at(stat_buf[48, 8].unpack('Q').first) # Creation time
62
+
63
+ @mode = 33188 if @chardev
64
+
65
+ attr = GetFileAttributes(file)
66
+
67
+ if attr == INVALID_FILE_ATTRIBUTES
68
+ raise ArgumentError, get_last_error
69
+ end
70
+
71
+ @blksize = get_blksize(file)
72
+
73
+ # This is a reasonable guess
74
+ case @blksize
75
+ when nil
76
+ @blocks = nil
77
+ when 0
78
+ @blocks = 0
79
+ else
80
+ @blocks = (@size.to_f / @blksize.to_f).ceil
81
+ end
82
+
83
+ @readonly = attr & FILE_ATTRIBUTE_READONLY > 0
84
+ @hidden = attr & FILE_ATTRIBUTE_HIDDEN > 0
85
+ @system = attr & FILE_ATTRIBUTE_SYSTEM > 0
86
+ @archive = attr & FILE_ATTRIBUTE_ARCHIVE > 0
87
+ @directory = attr & FILE_ATTRIBUTE_DIRECTORY > 0
88
+ @encrypted = attr & FILE_ATTRIBUTE_ENCRYPTED > 0
89
+ @normal = attr & FILE_ATTRIBUTE_NORMAL > 0
90
+ @temporary = attr & FILE_ATTRIBUTE_TEMPORARY > 0
91
+ @sparse = attr & FILE_ATTRIBUTE_SPARSE_FILE > 0
92
+ @reparse_point = attr & FILE_ATTRIBUTE_REPARSE_POINT > 0
93
+ @compressed = attr & FILE_ATTRIBUTE_COMPRESSED > 0
94
+ @offline = attr & FILE_ATTRIBUTE_OFFLINE > 0
95
+ @indexed = attr & ~FILE_ATTRIBUTE_NOT_CONTENT_INDEXED > 0
96
+
97
+ @executable = GetBinaryType(file, '')
98
+ @regular = @file_type == FILE_TYPE_DISK
99
+ @pipe = @file_type == FILE_TYPE_PIPE
100
+
101
+ # Not supported and/or meaningless
102
+ @dev_major = nil
103
+ @dev_minor = nil
104
+ @grpowned = true
105
+ @owned = true
106
+ @readable = true
107
+ @readable_real = true
108
+ @rdev_major = nil
109
+ @rdev_minor = nil
110
+ @setgid = false
111
+ @setuid = false
112
+ @sticky = false
113
+ @symlink = false
114
+ @writable = true
115
+ @writable_real = true
116
+ end
117
+
118
+ ## Comparable
119
+
120
+ # Compares two File::Stat objects. Comparsion is based on mtime only.
121
+ #
122
+ def <=>(other)
123
+ @mtime.to_i <=> other.mtime.to_i
124
+ end
125
+
126
+ ## Miscellaneous
127
+
128
+ def blockdev?
129
+ @blockdev
130
+ end
131
+
132
+ # Returns whether or not the file is a character device.
133
+ #
134
+ def chardev?
135
+ @chardev
136
+ end
137
+
138
+ # Returns whether or not the file is executable. Generally speaking, this
139
+ # means .bat, .cmd, .com, and .exe files.
140
+ #
141
+ def executable?
142
+ @executable
143
+ end
144
+
145
+ alias :executable_real? :executable?
146
+
147
+ # Returns whether or not the file is a regular file, as opposed to a pipe,
148
+ # socket, etc.
149
+ #
150
+ def file?
151
+ @regular
152
+ end
153
+
154
+ # Identifies the type of file. The return string is one of: file,
155
+ # directory, characterSpecial, socket or unknown.
156
+ #
157
+ def ftype
158
+ return 'directory' if directory?
159
+ case @file_type
160
+ when FILE_TYPE_CHAR
161
+ 'characterSpecial'
162
+ when FILE_TYPE_DISK
163
+ 'file'
164
+ when FILE_TYPE_PIPE
165
+ 'socket'
166
+ else
167
+ if blockdev?
168
+ 'blockSpecial'
169
+ else
170
+ 'unknown'
171
+ end
172
+ end
173
+ end
174
+
175
+ # Meaningless on Windows.
176
+ #
177
+ def grpowned?
178
+ @grpowned
179
+ end
180
+
181
+ # Always true on Windows
182
+ def owned?
183
+ @owned
184
+ end
185
+
186
+ # Returns whether or not the file is a pipe.
187
+ #
188
+ def pipe?
189
+ @pipe
190
+ end
191
+
192
+ alias :socket? :pipe?
193
+
194
+ # Meaningless on Windows
195
+ #
196
+ def readable?
197
+ @readable
198
+ end
199
+
200
+ # Meaningless on Windows
201
+ #
202
+ def readable_real?
203
+ @readable_real
204
+ end
205
+
206
+ # Meaningless on Windows
207
+ #
208
+ def setgid?
209
+ @setgid
210
+ end
211
+
212
+ # Meaningless on Windows
213
+ #
214
+ def setuid?
215
+ @setuid
216
+ end
217
+
218
+ # Returns nil if statfile is a zero-length file; otherwise, returns the
219
+ # file size. Usable as a condition in tests.
220
+ #
221
+ def size?
222
+ @size > 0 ? @size : nil
223
+ end
224
+
225
+ # Meaningless on Windows.
226
+ #
227
+ def sticky?
228
+ @sticky
229
+ end
230
+
231
+ # Meaningless on Windows at the moment. This may change in the future.
232
+ #
233
+ def symlink?
234
+ @symlink
235
+ end
236
+
237
+ # Meaningless on Windows.
238
+ #
239
+ def writable?
240
+ @writable
241
+ end
242
+
243
+ # Meaningless on Windows.
244
+ #
245
+ def writable_real?
246
+ @writable_real
247
+ end
248
+
249
+ # Returns whether or not the file size is zero.
250
+ #
251
+ def zero?
252
+ @size == 0
253
+ end
254
+
255
+ ## Attribute members
256
+
257
+ # Returns whether or not the file is an archive file.
258
+ #
259
+ def archive?
260
+ @archive
261
+ end
262
+
263
+ # Returns whether or not the file is compressed.
264
+ #
265
+ def compressed?
266
+ @compressed
267
+ end
268
+
269
+ # Returns whether or not the file is a directory.
270
+ #
271
+ def directory?
272
+ @directory
273
+ end
274
+
275
+ # Returns whether or not the file in encrypted.
276
+ #
277
+ def encrypted?
278
+ @encrypted
279
+ end
280
+
281
+ # Returns whether or not the file is hidden.
282
+ #
283
+ def hidden?
284
+ @hidden
285
+ end
286
+
287
+ # Returns whether or not the file is content indexed.
288
+ #
289
+ def indexed?
290
+ @indexed
291
+ end
292
+ alias :content_indexed? :indexed?
293
+
294
+ # Returns whether or not the file is 'normal'. This is only true if
295
+ # virtually all other attributes are false.
296
+ #
297
+ def normal?
298
+ @normal
299
+ end
300
+
301
+ # Returns whether or not the file is offline.
302
+ #
303
+ def offline?
304
+ @offline
305
+ end
306
+
307
+ # Returns whether or not the file is readonly.
308
+ #
309
+ def readonly?
310
+ @readonly
311
+ end
312
+
313
+ alias :read_only? :readonly?
314
+
315
+ # Returns whether or not the file is a reparse point.
316
+ #
317
+ def reparse_point?
318
+ @reparse_point
319
+ end
320
+
321
+ # Returns whether or not the file is a sparse file. In most cases a sparse
322
+ # file is an image file.
323
+ #
324
+ def sparse?
325
+ @sparse
326
+ end
327
+
328
+ # Returns whether or not the file is a system file.
329
+ #
330
+ def system?
331
+ @system
332
+ end
333
+
334
+ # Returns whether or not the file is being used for temporary storage.
335
+ #
336
+ def temporary?
337
+ @temporary
338
+ end
339
+
340
+ ## Standard stat members
341
+
342
+ # Returns a Time object containing the last access time.
343
+ #
344
+ def atime
345
+ @atime
346
+ end
347
+
348
+ # Returns the file system's block size, or nil if it cannot be determined.
349
+ #
350
+ def blksize
351
+ @blksize
352
+ end
353
+
354
+ # Returns the number of blocks used by the file, where a block is defined
355
+ # as size divided by blksize, rounded up.
356
+ #
357
+ # :no-doc:
358
+ # This is a fudge. A search of the internet reveals different ways people
359
+ # have defined st_blocks on MS Windows.
360
+ #
361
+ def blocks
362
+ @blocks
363
+ end
364
+
365
+ # Returns a Time object containing the time that the file status associated
366
+ # with the file was changed.
367
+ #
368
+ def ctime
369
+ @ctime
370
+ end
371
+
372
+ # Drive letter (A-Z) of the disk containing the file. If the path is a
373
+ # UNC path then the drive number (probably -1) is returned instead.
374
+ #
375
+ def dev
376
+ if PathIsUNC(@file)
377
+ @dev
378
+ else
379
+ (@dev + ?A).chr + ':'
380
+ end
381
+ end
382
+
383
+ # Group ID. Always 0.
384
+ #
385
+ def gid
386
+ @gid
387
+ end
388
+
389
+ # Inode number. Meaningless on NTFS.
390
+ #
391
+ def ino
392
+ @ino
393
+ end
394
+
395
+ # Bit mask for file-mode information.
396
+ #
397
+ # :no-doc:
398
+ # This was taken from rb_win32_stat() in win32.c. I'm not entirely
399
+ # sure what the point is.
400
+ #
401
+ def mode
402
+ @mode &= ~(S_IWGRP | S_IWOTH)
403
+ end
404
+
405
+ # Returns a Time object containing the modification time.
406
+ #
407
+ def mtime
408
+ @mtime
409
+ end
410
+
411
+ # Drive number of the disk containing the file.
412
+ #
413
+ def rdev
414
+ @rdev
415
+ end
416
+
417
+ # Always 1
418
+ #
419
+ def nlink
420
+ @nlink
421
+ end
422
+
423
+ # Returns the size of the file, in bytes.
424
+ #
425
+ def size
426
+ @size
427
+ end
428
+
429
+ # User ID. Always 0.
430
+ #
431
+ def uid
432
+ @uid
433
+ end
434
+
435
+ # Returns a stringified version of a File::Stat object.
436
+ #
437
+ def inspect
438
+ members = %w/
439
+ archive? atime blksize blocks compressed? ctime dev encrypted? gid
440
+ hidden? indexed? ino mode mtime rdev nlink normal? offline? readonly?
441
+ reparse_point? size sparse? system? temporary? uid
442
+ /
443
+ str = "#<#{self.class}"
444
+ members.sort.each{ |mem|
445
+ if mem == 'mode'
446
+ str << " #{mem}=" << sprintf("0%o", send(mem.intern))
447
+ elsif mem[-1].chr == '?'
448
+ str << " #{mem.chop}=" << send(mem.intern).to_s
449
+ else
450
+ str << " #{mem}=" << send(mem.intern).to_s
451
+ end
452
+ }
453
+ str
454
+ end
455
+
456
+ # A custom pretty print method. This was necessary not only to handle
457
+ # the additional attributes, but to work around an error caused by the
458
+ # builtin method for the current File::Stat class (see pp.rb).
459
+ #
460
+ def pretty_print(q)
461
+ members = %w/
462
+ archive? atime blksize blocks compressed? ctime dev encrypted? gid
463
+ hidden? indexed? ino mode mtime rdev nlink normal? offline? readonly?
464
+ reparse_point? size sparse? system? temporary? uid
465
+ /
466
+
467
+ q.object_group(self){
468
+ q.breakable
469
+ members.each{ |mem|
470
+ q.group{
471
+ q.text("#{mem}".ljust(15) + "=> ")
472
+ if mem == 'mode'
473
+ q.text(sprintf("0%o", send(mem.intern)))
474
+ else
475
+ val = self.send(mem.intern)
476
+ if val.nil?
477
+ q.text('nil')
478
+ else
479
+ q.text(val.to_s)
480
+ end
481
+ end
482
+ }
483
+ q.comma_breakable unless mem == members.last
484
+ }
485
+ }
486
+ end
487
+
488
+ private
489
+
490
+ # Returns the file system's block size.
491
+ #
492
+ def get_blksize(file)
493
+ size = nil
494
+
495
+ sectors = [0].pack('L')
496
+ bytes = [0].pack('L')
497
+ free = [0].pack('L')
498
+ total = [0].pack('L')
499
+
500
+ # If there's a drive letter it must contain a trailing backslash.
501
+ # The dup is necessary here because, for some odd reason, the function
502
+ # appears to modify the argument passed in.
503
+ if PathStripToRoot(file.dup)
504
+ file += "\\" unless file[-1].chr == "\\"
505
+ else
506
+ file = 0 # Default to root drive
507
+ end
508
+
509
+ # Don't check for an error here. Just default to nil.
510
+ if GetDiskFreeSpace(file, sectors, bytes, free, total)
511
+ size = sectors.unpack('L').first * bytes.unpack('L').first
512
+ end
513
+
514
+ size
515
+ end
516
+
517
+ # Returns the file's type (as a numeric).
518
+ #
519
+ def get_file_type(file)
520
+ handle = CreateFile(
521
+ file,
522
+ 0,
523
+ 0,
524
+ 0,
525
+ OPEN_EXISTING,
526
+ FILE_FLAG_BACKUP_SEMANTICS, # Need this for directories
527
+ 0
528
+ )
529
+
530
+ if handle == INVALID_HANDLE_VALUE
531
+ raise ArgumentError, get_last_error
532
+ end
533
+
534
+ file_type = GetFileType(handle)
535
+ error = GetLastError()
536
+
537
+ CloseHandle(handle)
538
+
539
+ if error == 0
540
+ if file_type == FILE_TYPE_DISK || file_type == FILE_TYPE_UNKNOWN
541
+ @blockdev = true
542
+ end
543
+ end
544
+
545
+ file_type
546
+ end
547
+
548
+ # Verifies that a value is either true or false
549
+ def check_bool(val)
550
+ raise TypeError unless val == true || val == false
551
+ end
552
+ end
@@ -0,0 +1 @@
1
+ This is a test
@@ -0,0 +1 @@
1
+ This is a test
@@ -0,0 +1,312 @@
1
+ #####################################################################
2
+ # tc_file_stat.rb
3
+ #
4
+ # Test case for stat related methods of win32-file.
5
+ #####################################################################
6
+ base = File.basename(Dir.pwd)
7
+
8
+ if base == 'test' || base =~ /win32-file-stat/
9
+ Dir.chdir('..') if base == 'test'
10
+ $LOAD_PATH.unshift(Dir.pwd + '/lib')
11
+ Dir.chdir('test') rescue nil
12
+ end
13
+
14
+ require 'test/unit'
15
+ require 'win32/file/stat'
16
+
17
+ class TC_Win32_File_Stat < Test::Unit::TestCase
18
+ include Windows::File
19
+ def setup
20
+ @file = 'sometestfile.txt'
21
+ @exe = 'sometestfile.exe'
22
+ @dir = Dir.pwd
23
+ @stat = File::Stat.new(@file)
24
+ end
25
+
26
+ def test_version
27
+ assert_equal('1.2.3', File::Stat::VERSION)
28
+ end
29
+
30
+ # One or more tests will fail if the archive attribute on @file is not set.
31
+ def test_archive
32
+ assert_respond_to(@stat, :archive?)
33
+ assert_nothing_raised{ @stat.archive? }
34
+ assert(@stat.archive?)
35
+ end
36
+
37
+ def test_atime
38
+ assert_respond_to(@stat, :atime)
39
+ assert_kind_of(Time, @stat.atime)
40
+ end
41
+
42
+ def test_blksize
43
+ assert_respond_to(@stat, :blksize)
44
+ assert_equal(4096, @stat.blksize)
45
+ end
46
+
47
+ def test_blockdev
48
+ assert_respond_to(@stat, :blockdev?)
49
+ assert_equal(true, @stat.blockdev?)
50
+ assert_equal(false, File::Stat.new('NUL').blockdev?)
51
+ end
52
+
53
+ def test_blocks
54
+ assert_respond_to(@stat, :blocks)
55
+ assert_equal(1, @stat.blocks)
56
+ end
57
+
58
+ def test_chardev
59
+ assert_respond_to(@stat, :chardev?)
60
+ assert_nothing_raised{ File::Stat.new("NUL").chardev? }
61
+ assert_equal(true, File::Stat.new("NUL").chardev?)
62
+ assert_equal(false, File::Stat.new("C:\\").chardev?)
63
+ end
64
+
65
+ def test_comparison
66
+ assert_respond_to(@stat, :<=>)
67
+ assert_nothing_raised{ @stat <=> File::Stat.new(@exe) }
68
+ end
69
+
70
+ def test_compressed
71
+ assert_respond_to(@stat, :compressed?)
72
+ assert_nothing_raised{ @stat.compressed? }
73
+ assert_equal(false, @stat.compressed?)
74
+ end
75
+
76
+ def test_ctime
77
+ assert_respond_to(@stat, :ctime)
78
+ assert_kind_of(Time, @stat.ctime)
79
+ end
80
+
81
+ # Assumes you've installed on C: drive.
82
+ def test_dev
83
+ assert_respond_to(@stat, :dev)
84
+ assert_equal('C:', @stat.dev)
85
+ end
86
+
87
+ def test_dev_major
88
+ assert_respond_to(@stat, :dev_major)
89
+ assert_nil(@stat.dev_major)
90
+ end
91
+
92
+ def test_dev_minor
93
+ assert_respond_to(@stat, :dev_minor)
94
+ assert_nil(@stat.dev_minor)
95
+ end
96
+
97
+ def test_directory
98
+ assert_respond_to(@stat, :directory?)
99
+ assert_equal(false, @stat.directory?)
100
+ assert_equal(true, File::Stat.new("C:\\").directory?)
101
+ end
102
+
103
+ def test_executable
104
+ assert_respond_to(@stat, :executable?)
105
+ assert_equal(false, @stat.executable?)
106
+ assert_equal(true, File::Stat.new(@exe).executable?)
107
+ end
108
+
109
+ def test_executable_real
110
+ assert_respond_to(@stat, :executable_real?)
111
+ assert_equal(false, @stat.executable_real?)
112
+ assert_equal(true, File::Stat.new(@exe).executable_real?)
113
+ end
114
+
115
+ def test_file
116
+ assert_respond_to(@stat, :file?)
117
+ assert_equal(true, @stat.file?)
118
+ assert_equal(true, File::Stat.new(@exe).file?)
119
+ assert_equal(true, File::Stat.new(Dir.pwd).file?)
120
+ assert_equal(false, File::Stat.new('NUL').file?)
121
+ end
122
+
123
+ def test_ftype
124
+ assert_respond_to(@stat, :ftype)
125
+ assert_equal('file', @stat.ftype)
126
+ assert_equal('characterSpecial', File::Stat.new('NUL').ftype)
127
+ assert_equal('directory', File::Stat.new(Dir.pwd).ftype)
128
+ end
129
+
130
+ def encrypted
131
+ assert_respond_to(@stat, :encrypted?)
132
+ assert_nothing_raised{ @stat.encrypted? }
133
+ end
134
+
135
+ def test_gid
136
+ assert_respond_to(@stat, :gid)
137
+ assert_equal(0, @stat.gid)
138
+ end
139
+
140
+ def test_grpowned
141
+ assert_respond_to(@stat, :grpowned?)
142
+ end
143
+
144
+ def test_hidden
145
+ assert_respond_to(@stat, :hidden?)
146
+ assert_nothing_raised{ @stat.hidden? }
147
+ assert_equal(false, @stat.hidden?)
148
+ end
149
+
150
+ def test_indexed
151
+ assert_respond_to(@stat, :indexed?)
152
+ assert_respond_to(@stat, :content_indexed?) # alias
153
+ assert_nothing_raised{ @stat.indexed? }
154
+ assert(@stat.indexed?)
155
+ end
156
+
157
+ def test_ino
158
+ assert_respond_to(@stat, :ino)
159
+ assert_equal(0, @stat.ino)
160
+ end
161
+
162
+ def test_inspect
163
+ assert_respond_to(@stat, :inspect)
164
+ end
165
+
166
+ def test_mode
167
+ assert_respond_to(@stat, :mode)
168
+ assert_equal(33188, File::Stat.new(@file).mode)
169
+ assert_equal(33261, File::Stat.new(@exe).mode)
170
+ assert_equal(16877, File::Stat.new(@dir).mode)
171
+
172
+ SetFileAttributes(@file, 1) # Set to readonly.
173
+ assert_equal(33060, File::Stat.new(@file).mode)
174
+ end
175
+
176
+ def test_mtime
177
+ assert_respond_to(@stat, :mtime)
178
+ assert_kind_of(Time, @stat.mtime)
179
+ end
180
+
181
+ def test_nlink
182
+ assert_respond_to(@stat, :nlink)
183
+ assert_equal(1, @stat.nlink)
184
+ end
185
+
186
+ def test_normal
187
+ assert_respond_to(@stat, :normal?)
188
+ assert_nothing_raised{ @stat.normal? }
189
+ assert(@stat.normal?)
190
+ end
191
+
192
+ def test_offline
193
+ assert_respond_to(@stat, :offline?)
194
+ assert_nothing_raised{ @stat.offline? }
195
+ assert_equal(false, @stat.offline?)
196
+ end
197
+
198
+ def test_pipe
199
+ assert_respond_to(@stat, :pipe?)
200
+ assert_equal(false, @stat.pipe?)
201
+ end
202
+
203
+ def test_readable
204
+ assert_respond_to(@stat, :readable?)
205
+ assert_equal(true, @stat.readable?)
206
+ end
207
+
208
+ def test_readable_real
209
+ assert_respond_to(@stat, :readable_real?)
210
+ assert_equal(true, @stat.readable_real?)
211
+ end
212
+
213
+ def test_readonly
214
+ assert_respond_to(@stat, :readonly?)
215
+ assert_nothing_raised{ @stat.readonly? }
216
+ assert_equal(false, @stat.readonly?)
217
+ end
218
+
219
+ def test_reparse_point
220
+ assert_respond_to(@stat, :reparse_point?)
221
+ assert_nothing_raised{ @stat.reparse_point? }
222
+ assert_equal(false, @stat.reparse_point?)
223
+ end
224
+
225
+ # Assumes you've installed on C: drive.
226
+ def test_rdev
227
+ msg = "ignore failure if Ruby is not installed on C: drive"
228
+ assert_respond_to(@stat, :rdev)
229
+ assert_equal(2, @stat.rdev, msg)
230
+ end
231
+
232
+ def test_setgid
233
+ assert_respond_to(@stat, :setgid?)
234
+ assert_equal(false, @stat.setgid?)
235
+ end
236
+
237
+ def test_setuid
238
+ assert_respond_to(@stat, :setuid?)
239
+ assert_equal(false, @stat.setuid?)
240
+ end
241
+
242
+ def test_size
243
+ assert_respond_to(@stat, :size)
244
+ assert_equal(16, @stat.size)
245
+ end
246
+
247
+ def test_size_bool
248
+ assert_respond_to(@stat, :size?)
249
+ assert_equal(16, @stat.size?)
250
+ end
251
+
252
+ def test_socket
253
+ assert_respond_to(@stat, :socket?)
254
+ assert_equal(false, @stat.socket?)
255
+ end
256
+
257
+ def test_sparse
258
+ assert_respond_to(@stat, :sparse?)
259
+ assert_nothing_raised{ @stat.sparse? }
260
+ assert_equal(false, @stat.sparse?)
261
+ end
262
+
263
+ def test_sticky
264
+ assert_respond_to(@stat, :sticky?)
265
+ assert_equal(false, @stat.sticky?)
266
+ end
267
+
268
+ def test_symlink
269
+ assert_respond_to(@stat, :symlink?)
270
+ assert_equal(false, @stat.symlink?)
271
+ end
272
+
273
+ def test_system
274
+ assert_respond_to(@stat, :system?)
275
+ assert_nothing_raised{ @stat.system? }
276
+ assert_equal(false, @stat.system?)
277
+ end
278
+
279
+ def test_temporary
280
+ assert_respond_to(@stat, :temporary?)
281
+ assert_nothing_raised{ @stat.temporary? }
282
+ assert_equal(false, @stat.temporary?)
283
+ end
284
+
285
+ def test_uid
286
+ assert_respond_to(@stat, :uid)
287
+ assert_equal(0, @stat.uid)
288
+ end
289
+
290
+ def test_writable
291
+ assert_respond_to(@stat, :writable?)
292
+ assert_equal(true, @stat.writable?)
293
+ end
294
+
295
+ def test_writable_real
296
+ assert_respond_to(@stat, :writable_real?)
297
+ assert_equal(true, @stat.writable_real?)
298
+ end
299
+
300
+ def test_zero
301
+ assert_respond_to(@stat, :zero?)
302
+ assert_equal(false, @stat.zero?)
303
+ end
304
+
305
+ def teardown
306
+ SetFileAttributes(@file, 8) # Set file back to normal
307
+ @file = nil
308
+ @exe = nil
309
+ @dir = nil
310
+ @stat = nil
311
+ end
312
+ end
@@ -0,0 +1,24 @@
1
+ require "rubygems"
2
+
3
+ spec = Gem::Specification.new do |gem|
4
+ gem.name = "win32-file-stat"
5
+ gem.version = "1.2.3"
6
+ gem.author = "Daniel J. Berger"
7
+ gem.email = "djberg96@gmail.com"
8
+ gem.homepage = "http://www.rubyforge.org/projects/win32utils"
9
+ gem.platform = Gem::Platform::RUBY
10
+ gem.summary = "A File::Stat class tailored to MS Windows"
11
+ gem.description = "A File::Stat class tailored to MS Windows"
12
+ gem.test_file = "test/tc_file_stat.rb"
13
+ gem.has_rdoc = true
14
+ gem.files = Dir['lib/win32/file/*.rb'] + Dir['[A-Z]*'] + Dir['test/*']
15
+ gem.files.reject! { |fn| fn.include? "CVS" }
16
+ gem.require_path = "lib"
17
+ gem.extra_rdoc_files = ["README", "CHANGES"]
18
+ gem.add_dependency("windows-pr", ">= 0.4.0")
19
+ end
20
+
21
+ if $0 == __FILE__
22
+ Gem.manage_gems
23
+ Gem::Builder.new(spec).build
24
+ end
metadata ADDED
@@ -0,0 +1,65 @@
1
+ --- !ruby/object:Gem::Specification
2
+ rubygems_version: 0.9.0
3
+ specification_version: 1
4
+ name: win32-file-stat
5
+ version: !ruby/object:Gem::Version
6
+ version: 1.2.3
7
+ date: 2006-11-04 00:00:00 -07:00
8
+ summary: A File::Stat class tailored to MS Windows
9
+ require_paths:
10
+ - lib
11
+ email: djberg96@gmail.com
12
+ homepage: http://www.rubyforge.org/projects/win32utils
13
+ rubyforge_project:
14
+ description: A File::Stat class tailored to MS Windows
15
+ autorequire:
16
+ default_executable:
17
+ bindir: bin
18
+ has_rdoc: true
19
+ required_ruby_version: !ruby/object:Gem::Version::Requirement
20
+ requirements:
21
+ - - ">"
22
+ - !ruby/object:Gem::Version
23
+ version: 0.0.0
24
+ version:
25
+ platform: ruby
26
+ signing_key:
27
+ cert_chain:
28
+ post_install_message:
29
+ authors:
30
+ - Daniel J. Berger
31
+ files:
32
+ - lib/win32/file/stat.rb
33
+ - CHANGES
34
+ - install.rb
35
+ - lib
36
+ - MANIFEST
37
+ - README
38
+ - test
39
+ - win32-file-stat.gemspec
40
+ - test/sometestfile.exe
41
+ - test/sometestfile.txt
42
+ - test/tc_file_stat.rb
43
+ test_files:
44
+ - test/tc_file_stat.rb
45
+ rdoc_options: []
46
+
47
+ extra_rdoc_files:
48
+ - README
49
+ - CHANGES
50
+ executables: []
51
+
52
+ extensions: []
53
+
54
+ requirements: []
55
+
56
+ dependencies:
57
+ - !ruby/object:Gem::Dependency
58
+ name: windows-pr
59
+ version_requirement:
60
+ version_requirements: !ruby/object:Gem::Version::Requirement
61
+ requirements:
62
+ - - ">="
63
+ - !ruby/object:Gem::Version
64
+ version: 0.4.0
65
+ version: