win32-file-stat 1.2.3

Sign up to get free protection for your applications and to get access to all the features.
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: