Class: FakeFS::File

Inherits:
StringIO
  • Object
show all
Defined in:
lib/fakefs/file.rb,
lib/fakefs/flockable_file.rb

Overview

Be careful using this, as it may break things if you obtain more that one flock per file using different descriptors. Real flock call blocks/returns false in that case - see man7.org/linux/man-pages/man2/flock.2.html, it says it “may be denied”, but it does, it fact, deny. This implementation simply returns 0. This may also be a problem if you, it fact, are accessing a real file, which is locked by another process.

Defined Under Namespace

Classes: Stat

Constant Summary collapse

MODES =
[
  READ_ONLY           = 'r',
  READ_WRITE          = 'r+',
  WRITE_ONLY          = 'w',
  READ_WRITE_TRUNCATE = 'w+',
  APPEND_WRITE_ONLY   = 'a',
  APPEND_READ_WRITE   = 'a+'
].freeze
FMODE_READABLE =
0x00000001
FMODE_WRITABLE =
0x00000002
FMODE_READWRITE =
(FMODE_READABLE | FMODE_WRITABLE)
FMODE_BINMODE =
0x00000004
FMODE_APPEND =
0x00000040
FMODE_CREATE =
0x00000080
FMODE_EXCL =
0x00000400
FMODE_TRUNC =
0x00000800
FMODE_TEXTMODE =
0x00001000
TEXT_MODES =
{
  'r' => FMODE_READABLE,
  'w' => FMODE_WRITABLE | FMODE_TRUNC | FMODE_CREATE,
  'a' => FMODE_WRITABLE | FMODE_APPEND | FMODE_CREATE
}.freeze
FILE_CREATION_MODES =
(MODES - [READ_ONLY, READ_WRITE]).freeze
FILE_ACCESS_MODE =
(RealFile::RDONLY | RealFile::WRONLY | RealFile::RDWR)
MODE_BITMASK =
(
  RealFile::RDONLY |
  RealFile::WRONLY |
  RealFile::RDWR |
  RealFile::APPEND |
  RealFile::CREAT |
  RealFile::EXCL |
  RealFile::NONBLOCK |
  RealFile::TRUNC |
  RealFile::BINARY |
  (RealFile.const_defined?(:NOCTTY) ? RealFile::NOCTTY : 0) |
  (RealFile.const_defined?(:SYNC) ? RealFile::SYNC : 0)
)
DEFAULT_DIR_SIZE =
64
DIR_ENTRY_SIZE =
32
FAKE_FS_ALLOWED_FLOCK_MODES =

yep, File::LOCK_UN | File::LOCK_NB is allowed

[RealFile::LOCK_EX, RealFile::LOCK_SH, RealFile::LOCK_UN].flat_map do |mode|
  [mode, mode | RealFile::LOCK_NB]
end.freeze

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(path, *args) ⇒ File

Returns a new instance of File.

Raises:

  • (ArgumentError)


501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
# File 'lib/fakefs/file.rb', line 501

def initialize(path, *args)
  # unable to pass args otherwise on jruby, it may cause false passes on MRI, though
  # because explicit hash isn't supported
  opts = args.last.is_a?(Hash) ? args.pop : {}
  if args.size > 2
    raise ArgumentError, "wrong number of arguments (given #{args.size + 1}, expected 1..3)"
  end
  mode, _perm = args

  @path = path
  @file = FileSystem.find(@path)
  # real rb_scan_open_args - and rb_io_extract_modeenc - is much more complex
  raise ArgumentError, 'mode specified twice' unless mode.nil? || opts[:mode].nil?

  mode_opt = mode.nil? ? opts[:mode] : mode
  # see vmode_handle
  if mode_opt.nil?
    @oflags = RealFile::RDONLY
  elsif mode_opt.respond_to?(:to_int) && (intmode = mode_opt.to_int).instance_of?(Integer)
    @oflags = intmode
  else
    unless mode_opt.is_a?(String)
      unless mode_opt.respond_to?(:to_str)
        raise TypeError, "no implicit conversion of #{mode_opt.class} into String"
      end

      strmode = mode_opt.to_str
      unless strmode.is_a?(String)
        raise TypeError, "can't convert #{mode_opt.class} to String " \
          "(#{mode_opt.class}#to_str gives #{strmode.class})"
      end

      mode_opt = strmode
    end

    @oflags, @fmode = parse_strmode_oflags(mode_opt)
  end
  unless opts[:flags].nil?
    if opts[:flags].is_a?(Integer)
      @oflags |= opts[:flags]
    elsif opts[:flags].respond_to?(:to_int)
      intflags = opts[:flags].to_int
      unless intflags.instance_of?(Integer)
        raise TypeError, "can't convert #{opts[:flags].class} to Integer " \
          "(#{opts[:flags].class}#to_int gives #{intflags.class})"
      end

      @oflags |= intflags
      @fmode = create_fmode(@oflags)
    else
      raise TypeError, "no implicit conversion of #{opts[:flags].class} into Integer"
    end
  end
  @fmode ||= create_fmode(@oflags)
  @fmode = extract_binmode(opts, @fmode)

  @autoclose = true
  file_creation_mode? ? create_missing_file : check_file_existence!
  # StringIO changes enciding of the underlying string to binary
  # when binary data is written if it's opened in binary mode,
  # so content might have binary encoding. StringIO also switches to
  # binary mode if its string have binary encoding, but it might not
  # be what we want, so insteed we use encoding parsed after super call
  # and force set it back.

  # truncate doesn't work
  unless @file.is_a?(FakeFS::FakeDir)
    @file.content = @file.content.dup.force_encoding(Encoding.default_external)
  end
  # StringIO.new 'content', nil, **{} # works in MRI, but fails in JRuby
  # but File.open 'filename', nil, **{} is ok both in MRI and JRuby

  # JRuby StringIO doesn't support kwargs without mode
  #  StringIO.new "buff", encoding: 'binary' # work on MRI, fails on JRuby
  if RUBY_PLATFORM == "java"
    # other opts aren't supported
    super(@file.content, mode_opt || 'r')
    binmode if binmode? # Looks like it doesn't care about 'b'
    mode_opt_str = mode_opt.is_a?(String) ? mode_opt : ''
    raise ArgumentError, 'encoding specified twice' if mode_opt_str[':'] && opts[:encoding]

    # Might raise where real File just warns
    str_encoding = mode_opt_str.split(':')[1] # internal encoding is ignored anyway
    if opts[:encoding]
      set_encoding(opts[:encoding])
    elsif str_encoding && str_encoding != ''
      set_encoding(str_encoding)
    elsif opts[:binmode]
      set_encoding(Encoding::BINARY)
    end
  else
    super(@file.content, mode, **opts)
  end

  # StringIO is wrtable and readable by default, so we need to disable it
  # but maybe it was explicitly disabled by opts
  close_write if @fmode & FMODE_WRITABLE == 0 && !StringIO.instance_method(:closed_write?).bind(self).call
  close_read if @fmode & FMODE_READABLE == 0 && !StringIO.instance_method(:closed_read?).bind(self).call
end

Instance Attribute Details

#autocloseObject

Returns the value of attribute autoclose.



740
741
742
# File 'lib/fakefs/file.rb', line 740

def autoclose
  @autoclose
end

#pathObject (readonly)

Returns the value of attribute path.



499
500
501
# File 'lib/fakefs/file.rb', line 499

def path
  @path
end

Class Method Details

.absolute_path(file_name, dir_name = Dir.getwd) ⇒ Object



736
737
738
# File 'lib/fakefs/file.rb', line 736

def self.absolute_path(file_name, dir_name = Dir.getwd)
  RealFile.absolute_path(file_name, dir_name)
end

.basename(*args) ⇒ Object



178
179
180
# File 'lib/fakefs/file.rb', line 178

def self.basename(*args)
  RealFile.basename(*args)
end

.binread(file, length = nil, offset = 0) ⇒ Object



337
338
339
# File 'lib/fakefs/file.rb', line 337

def self.binread(file, length = nil, offset = 0)
  File.read(file, length, offset, mode: 'rb:ASCII-8BIT')
end

.binwrite(file, content, offset = nil) ⇒ Object



341
342
343
344
# File 'lib/fakefs/file.rb', line 341

def self.binwrite(file, content, offset = nil)
  mode = offset ? 'r+b:ASCII-8BIT' : 'wb:ASCII-8BIT'
  File.write(file, content, offset, mode: mode)
end

.birthtime(path) ⇒ Object



788
789
790
791
792
793
794
# File 'lib/fakefs/file.rb', line 788

def self.birthtime(path)
  if exist?(path)
    FileSystem.find(path).birthtime
  else
    raise Errno::ENOENT
  end
end

.chmod(new_mode, filename) ⇒ Object



300
301
302
303
304
305
306
307
308
309
310
# File 'lib/fakefs/file.rb', line 300

def self.chmod(new_mode, filename)
  # chmod's mode can either be passed in in absolute mode, or symbolic mode
  # for reference: https://ruby-doc.org/stdlib-2.2.2/libdoc/fileutils/rdoc/FileUtils.html#method-c-chmod
  # if the mode is passed in symbolic mode we must convert it to absolute mode
  is_absolute_mode = new_mode.is_a? Numeric
  unless is_absolute_mode
    current_mode = FileSystem.find(filename).mode
    new_mode = convert_symbolic_chmod_to_absolute(new_mode, current_mode)
  end
  FileSystem.find(filename).mode = 0o100000 + new_mode
end

.chown(owner_int, group_int, filename) ⇒ Object



320
321
322
323
324
325
326
327
328
329
330
331
# File 'lib/fakefs/file.rb', line 320

def self.chown(owner_int, group_int, filename)
  file = FileSystem.find(filename)

  if owner_int && owner_int != -1
    owner_int.is_a?(Integer) || raise(TypeError, "can't convert String into Integer")
    file.uid = owner_int
  end
  if group_int && group_int != -1
    group_int.is_a?(Integer) || raise(TypeError, "can't convert String into Integer")
    file.gid = group_int
  end
end

.const_missing(name) ⇒ Object



140
141
142
# File 'lib/fakefs/file.rb', line 140

def self.const_missing(name)
  RealFile.const_get(name)
end

.delete(*files) ⇒ Object Also known as: unlink



269
270
271
272
273
274
275
276
277
278
# File 'lib/fakefs/file.rb', line 269

def self.delete(*files)
  files.each do |file|
    file_name = (file.instance_of?(FakeFS::File) ? file.path : file.to_s)
    raise Errno::ENOENT, file_name unless exist?(file_name)

    FileUtils.rm(file_name)
  end

  files.size
end

.directory?(path) ⇒ Boolean



144
145
146
147
148
149
150
151
# File 'lib/fakefs/file.rb', line 144

def self.directory?(path)
  if path.respond_to? :entry
    path.entry.is_a? FakeDir
  else
    result = FileSystem.find(path)
    result ? result.entry.is_a?(FakeDir) : false
  end
end

.dirname(*args) ⇒ Object



182
183
184
# File 'lib/fakefs/file.rb', line 182

def self.dirname(*args)
  RealFile.dirname(*args)
end

.executable?(filename) ⇒ Boolean

Not exactly right, returns true if the file is chmod +x for owner. In the context of when you would use fakefs, this is usually what you want.



314
315
316
317
318
# File 'lib/fakefs/file.rb', line 314

def self.executable?(filename)
  file = FileSystem.find(filename)
  return false unless file
  (file.mode - 0o100000) & 0o100 != 0
end

.exist?(path) ⇒ Boolean



66
67
68
69
70
71
72
73
# File 'lib/fakefs/file.rb', line 66

def self.exist?(path)
  if File.symlink?(path)
    referent = File.expand_path(File.readlink(path), File.dirname(path))
    exist?(referent)
  else
    !FileSystem.find(path).nil?
  end
end

.expand_path(file_name, dir_string = FileSystem.current_dir.to_s) ⇒ Object



174
175
176
# File 'lib/fakefs/file.rb', line 174

def self.expand_path(file_name, dir_string = FileSystem.current_dir.to_s)
  RealFile.expand_path(file_name, RealFile.expand_path(dir_string, Dir.pwd))
end

.extname(path) ⇒ Object



54
55
56
# File 'lib/fakefs/file.rb', line 54

def self.extname(path)
  RealFile.extname(path)
end

.file?(path) ⇒ Boolean



161
162
163
164
165
166
167
168
# File 'lib/fakefs/file.rb', line 161

def self.file?(path)
  if path.respond_to? :entry
    path.entry.is_a? FakeFile
  else
    result = FileSystem.find(path)
    result ? result.entry.is_a?(FakeFile) : false
  end
end

.fnmatch?(pattern, path, flags = 0) ⇒ Boolean Also known as: fnmatch



346
347
348
# File 'lib/fakefs/file.rb', line 346

def self.fnmatch?(pattern, path, flags = 0)
  RealFile.fnmatch?(pattern, path, flags)
end

.foreach(path, *args, &block) ⇒ Object



217
218
219
220
221
222
223
224
225
226
227
228
229
# File 'lib/fakefs/file.rb', line 217

def self.foreach(path, *args, &block)
  file = new(path)
  if file.exists?
    FileSystem.find(path).atime = Time.now
    if block_given?
      file.each_line(*args, &block)
    else
      file.each_line(*args)
    end
  else
    raise Errno::ENOENT
  end
end

.ftype(filename) ⇒ Object



170
171
172
# File 'lib/fakefs/file.rb', line 170

def self.ftype(filename)
  File.lstat(filename).ftype
end

.identical?(one_path, another_path) ⇒ Boolean



76
77
78
# File 'lib/fakefs/file.rb', line 76

def identical?(one_path, another_path)
  FileSystem.find(one_path) == FileSystem.find(another_path)
end

.join(*parts) ⇒ Object



58
59
60
# File 'lib/fakefs/file.rb', line 58

def self.join(*parts)
  RealFile.join(parts)
end

Raises:

  • (Errno::EPERM)


257
258
259
260
261
262
263
264
265
266
267
# File 'lib/fakefs/file.rb', line 257

def self.link(source, dest)
  raise Errno::EPERM, "#{source} or #{dest}" if directory?(source)
  raise Errno::ENOENT, "#{source} or #{dest}" unless exist?(source)
  raise Errno::EEXIST, "#{source} or #{dest}" if exist?(dest)

  source = FileSystem.find(source)
  dest = FileSystem.add(dest, source.entry.clone)
  source.link(dest)

  0
end

.lstat(file) ⇒ Object



292
293
294
# File 'lib/fakefs/file.rb', line 292

def self.lstat(file)
  File::Stat.new(file, true)
end

.path(file) ⇒ Object



62
63
64
# File 'lib/fakefs/file.rb', line 62

def self.path(file)
  RealFile.path(file)
end

.read(path, *args) ⇒ Object

TODO: support open_key_args

Raises:

  • (Errno::ENOENT)


193
194
195
196
197
198
199
200
201
202
203
204
205
# File 'lib/fakefs/file.rb', line 193

def self.read(path, *args)
  options = args[-1].is_a?(Hash) ? args.pop : {}
  length = args.empty? ? nil : args.shift
  offset = args.empty? ? 0 : args.shift
  file = new(path, **options)

  raise Errno::ENOENT unless file.exists?
  raise Errno::EISDIR, path.to_s if directory?(path)

  FileSystem.find(path).atime = Time.now
  file.seek(offset)
  file.read(length)
end

.readable?(path) ⇒ Boolean



86
87
88
89
# File 'lib/fakefs/file.rb', line 86

def self.readable?(path)
  return false unless exist? path
  File.lstat(path).readable?
end

.readlines(path, chomp: false) ⇒ Object



207
208
209
210
211
212
213
214
215
# File 'lib/fakefs/file.rb', line 207

def self.readlines(path, chomp: false)
  file = new(path)
  if file.exists?
    FileSystem.find(path).atime = Time.now
    chomp ? file.readlines.map(&:chomp) : file.readlines
  else
    raise Errno::ENOENT
  end
end

Raises:

  • (Errno::ENOENT)


186
187
188
189
190
# File 'lib/fakefs/file.rb', line 186

def self.readlink(path)
  symlink = FileSystem.find(path)
  raise Errno::ENOENT unless symlink
  symlink.target
end

.realdirpath(*args) ⇒ Object



752
753
754
# File 'lib/fakefs/file.rb', line 752

def self.realdirpath(*args)
  RealFile.realdirpath(*args)
end

.realpath(*args) ⇒ Object



715
716
717
# File 'lib/fakefs/file.rb', line 715

def self.realpath(*args)
  RealFile.realpath(*args)
end

.rename(source, dest) ⇒ Object



231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
# File 'lib/fakefs/file.rb', line 231

def self.rename(source, dest)
  if directory?(source) && file?(dest)
    raise Errno::ENOTDIR, "#{source} or #{dest}"
  elsif file?(source) && directory?(dest)
    raise Errno::EISDIR, "#{source} or #{dest}"
  elsif !exist?(dirname(dest))
    raise Errno::ENOENT, "#{source} or #{dest}"
  end

  if (target = FileSystem.find(source))
    return 0 if source == dest

    if target.is_a?(FakeFS::FakeSymlink)
      File.symlink(target.target, dest)
    else
      FileSystem.add(dest, target.entry.clone)
    end

    FileSystem.delete(source)
  else
    raise Errno::ENOENT, "#{source} or #{dest}"
  end

  0
end

.size(path) ⇒ Object



120
121
122
123
124
125
126
# File 'lib/fakefs/file.rb', line 120

def self.size(path)
  if directory?(path)
    DEFAULT_DIR_SIZE + (DIR_ENTRY_SIZE * FileSystem.find(path).entries.size)
  else
    read(path).bytesize
  end
end

.size?(path) ⇒ Boolean



128
129
130
# File 'lib/fakefs/file.rb', line 128

def self.size?(path)
  size(path) if exist?(path) && !size(path).zero?
end

.split(path) ⇒ Object



296
297
298
# File 'lib/fakefs/file.rb', line 296

def self.split(path)
  RealFile.split(path)
end

.stat(file) ⇒ Object



288
289
290
# File 'lib/fakefs/file.rb', line 288

def self.stat(file)
  File::Stat.new(file)
end

.sticky?(_path) ⇒ Boolean

Assume nothing is sticky.



81
82
83
# File 'lib/fakefs/file.rb', line 81

def sticky?(_path)
  false
end


284
285
286
# File 'lib/fakefs/file.rb', line 284

def self.symlink(source, dest)
  FileUtils.ln_s(source, dest)
end

.symlink?(path) ⇒ Boolean



153
154
155
156
157
158
159
# File 'lib/fakefs/file.rb', line 153

def self.symlink?(path)
  if path.respond_to? :entry
    path.is_a? FakeSymlink
  else
    FileSystem.find(path).is_a? FakeSymlink
  end
end

.umask(*args) ⇒ Object



333
334
335
# File 'lib/fakefs/file.rb', line 333

def self.umask(*args)
  RealFile.umask(*args)
end

.utime(atime, mtime, *paths) ⇒ Object



106
107
108
109
110
111
112
113
114
115
116
117
118
# File 'lib/fakefs/file.rb', line 106

def self.utime(atime, mtime, *paths)
  paths.each do |path|
    file_node = FileSystem.find(path)
    if file_node
      file_node.atime = atime
      file_node.mtime = mtime
    else
      raise Errno::ENOENT, "No such file or directory - #{path}"
    end
  end

  paths.size
end

.writable?(path) ⇒ Boolean



91
92
93
94
# File 'lib/fakefs/file.rb', line 91

def self.writable?(path)
  return false unless exist? path
  File.lstat(path).writable?
end

.write(filename, contents, offset = nil, **open_args) ⇒ Object



758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
# File 'lib/fakefs/file.rb', line 758

def self.write(filename, contents, offset = nil, **open_args)
  mode = offset ? 'r+' : 'w'
  if open_args[:open_args]
    # see open_key_args
    # todo: foreach, readlines, read also use it
    # Treat a final argument as keywords if it is a hash, and not as keywords otherwise.
    open_args = open_args[:open_args]
    if open_args.last.is_a?(Hash)
      args = open_args[0...-1]
      opt = open_args.last
    else
      args = open_args
      opt = {}
    end
  else
    args = [open_args.delete(:mode) || mode]
    opt = open_args
  end
  if offset
    open(filename, *args, **opt) do |f| # rubocop:disable Security/Open
      f.seek(offset)
      f.write(contents)
    end
  else
    open(filename, *args, **opt) do |f| # rubocop:disable Security/Open
      f.write(contents)
    end
  end
end

.zero?(path) ⇒ Boolean Also known as: empty?



132
133
134
# File 'lib/fakefs/file.rb', line 132

def self.zero?(path)
  exist?(path) && size(path) == 0
end

Instance Method Details

#advise(_advice, _offset = 0, _len = 0) ⇒ Object



756
# File 'lib/fakefs/file.rb', line 756

def advise(_advice, _offset = 0, _len = 0); end

#atimeObject



673
674
675
# File 'lib/fakefs/file.rb', line 673

def atime
  self.class.atime(@path)
end

#autoclose?Boolean



742
743
744
# File 'lib/fakefs/file.rb', line 742

def autoclose?
  @autoclose ? true : false
end

#binmode?Boolean



719
720
721
722
# File 'lib/fakefs/file.rb', line 719

def binmode?
  # File.open('test_mode', mode: 'w:binary').binmode? # => false
  @fmode & FMODE_BINMODE != 0
end

#birthtimeObject



796
797
798
# File 'lib/fakefs/file.rb', line 796

def birthtime
  self.class.birthtime(@path)
end

#chmod(new_mode) ⇒ Object



689
690
691
692
693
694
695
696
697
698
699
# File 'lib/fakefs/file.rb', line 689

def chmod(new_mode)
  # chmod's mode can either be passed in in absolute mode, or symbolic mode
  # for reference: https://ruby-doc.org/stdlib-2.2.2/libdoc/fileutils/rdoc/FileUtils.html#method-c-chmod
  # if the mode is passed in symbolic mode we must convert it to absolute mode
  is_absolute_mode = new_mode.is_a? Numeric
  unless is_absolute_mode
    current_mode = @file.mode
    new_mode = convert_symbolic_chmod_to_absolute(new_mode, current_mode)
  end
  @file.mode = 0o100000 + new_mode
end

#chown(owner_int, group_int) ⇒ Object



701
702
703
704
705
706
707
708
709
710
711
712
713
# File 'lib/fakefs/file.rb', line 701

def chown(owner_int, group_int)
  return unless group_int && group_int != -1

  owner_int.is_a?(Integer) || raise(
    TypeError, "can't convert String into Integer"
  )
  @file.uid = owner_int

  group_int.is_a?(Integer) || raise(
    TypeError, "can't convert String into Integer"
  )
  @file.gid = group_int
end

#close_on_exec=(_bool) ⇒ Object

Raises:

  • (NotImplementedError)


724
725
726
# File 'lib/fakefs/file.rb', line 724

def close_on_exec=(_bool)
  raise NotImplementedError
end

#close_on_exec?Boolean

Raises:

  • (NotImplementedError)


728
729
730
# File 'lib/fakefs/file.rb', line 728

def close_on_exec?
  raise NotImplementedError
end

#ctimeObject



677
678
679
# File 'lib/fakefs/file.rb', line 677

def ctime
  self.class.ctime(@path)
end

#exists?Boolean



601
602
603
# File 'lib/fakefs/file.rb', line 601

def exists?
  true
end

#flock(mode) ⇒ Object

Raises:

  • (NotImplementedError)


681
682
683
# File 'lib/fakefs/file.rb', line 681

def flock(*)
  raise NotImplementedError
end

#ioctlObject

Raises:

  • (NotImplementedError)


638
639
640
# File 'lib/fakefs/file.rb', line 638

def ioctl(*)
  raise NotImplementedError
end

#is_a?(klass) ⇒ Boolean



630
631
632
# File 'lib/fakefs/file.rb', line 630

def is_a?(klass)
  RealFile.allocate.is_a?(klass)
end

#lstatObject



650
651
652
# File 'lib/fakefs/file.rb', line 650

def lstat
  self.class.lstat(@path)
end

#mtimeObject



685
686
687
# File 'lib/fakefs/file.rb', line 685

def mtime
  self.class.mtime(@path)
end

#read_nonblockObject

Raises:

  • (NotImplementedError)


642
643
644
# File 'lib/fakefs/file.rb', line 642

def read_nonblock
  raise NotImplementedError
end

#readpartialObject



669
670
671
# File 'lib/fakefs/file.rb', line 669

def readpartial(*)
  super
end

#sizeObject



748
749
750
# File 'lib/fakefs/file.rb', line 748

def size
  File.size(@path)
end

#statObject



646
647
648
# File 'lib/fakefs/file.rb', line 646

def stat
  self.class.stat(@path)
end

#stringObject



634
635
636
# File 'lib/fakefs/file.rb', line 634

def string
  gets(nil)
end

#sysseek(position, whence = SEEK_SET) ⇒ Object



654
655
656
657
# File 'lib/fakefs/file.rb', line 654

def sysseek(position, whence = SEEK_SET)
  seek(position, whence)
  pos
end

#syswriteObject



613
614
615
616
617
# File 'lib/fakefs/file.rb', line 613

def write(*args)
  val = super(*args)
  @file.mtime = Time.now
  val
end

#to_ioObject



661
662
663
# File 'lib/fakefs/file.rb', line 661

def to_io
  self
end

#to_pathObject



732
733
734
# File 'lib/fakefs/file.rb', line 732

def to_path
  @path
end

#write(*args) ⇒ Object



605
606
607
608
609
# File 'lib/fakefs/file.rb', line 605

def write(*args)
  val = super(*args)
  @file.mtime = Time.now
  val
end

#write_nonblockObject

Raises:

  • (NotImplementedError)


665
666
667
# File 'lib/fakefs/file.rb', line 665

def write_nonblock(*)
  raise NotImplementedError
end