class FakeFS::File
FakeFS
File
class inherit StringIO
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.
Constants
- FAKE_FS_ALLOWED_FLOCK_MODES
-
yep, File::LOCK_UN | File::LOCK_NB is allowed
- FILE_ACCESS_MODE
- FILE_CREATION_MODES
- FMODE_APPEND
- FMODE_BINMODE
- FMODE_CREATE
- FMODE_EXCL
- FMODE_READABLE
- FMODE_READWRITE
- FMODE_TEXTMODE
- FMODE_TRUNC
- FMODE_WRITABLE
- MODES
- MODE_BITMASK
-
copied from github.com/ruby/ruby/blob/v2_7_8/include/ruby/io.h#L108
- TEXT_MODES
Attributes
Public Class Methods
Source
# File lib/fakefs/file.rb, line 747 def self.absolute_path(file_name, dir_name = Dir.getwd) RealFile.absolute_path(file_name, dir_name) end
Source
# File lib/fakefs/file.rb, line 109 def self.atime(path) if exist?(path) FileSystem.find(path).atime else raise Errno::ENOENT end end
Source
# File lib/fakefs/file.rb, line 190 def self.basename(*args) RealFile.basename(*args) end
Source
# File lib/fakefs/file.rb, line 348 def self.binread(file, length = nil, offset = 0) File.read(file, length, offset, mode: 'rb:ASCII-8BIT') end
Source
# File lib/fakefs/file.rb, line 352 def self.binwrite(file, content, offset = nil) mode = offset ? 'r+b:ASCII-8BIT' : 'wb:ASCII-8BIT' File.write(file, content, offset, mode: mode) end
Source
# File lib/fakefs/file.rb, line 799 def self.birthtime(path) if exist?(path) FileSystem.find(path).birthtime else raise Errno::ENOENT end end
Source
# File lib/fakefs/file.rb, line 311 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
Source
# File lib/fakefs/file.rb, line 331 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
Source
# File lib/fakefs/file.rb, line 152 def self.const_missing(name) RealFile.const_get(name) end
Source
# File lib/fakefs/file.rb, line 101 def self.ctime(path) if exist?(path) FileSystem.find(path).ctime else raise Errno::ENOENT end end
Source
# File lib/fakefs/file.rb, line 280 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
Source
# File lib/fakefs/file.rb, line 156 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
Source
# File lib/fakefs/file.rb, line 194 def self.dirname(*args) RealFile.dirname(*args) end
Source
# File lib/fakefs/file.rb, line 325 def self.executable?(filename) file = FileSystem.find(filename) return false unless file (file.mode - 0o100000) & 0o100 != 0 end
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.
Source
# File lib/fakefs/file.rb, line 63 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
Source
# File lib/fakefs/file.rb, line 186 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
Source
# File lib/fakefs/file.rb, line 51 def self.extname(path) RealFile.extname(path) end
Source
# File lib/fakefs/file.rb, line 173 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
Source
# File lib/fakefs/file.rb, line 357 def self.fnmatch?(pattern, path, flags = 0) RealFile.fnmatch?(pattern, path, flags) end
Source
# File lib/fakefs/file.rb, line 228 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
Source
# File lib/fakefs/file.rb, line 182 def self.ftype(filename) File.lstat(filename).ftype end
Source
# File lib/fakefs/file.rb, line 73 def identical?(one_path, another_path) FileSystem.find(one_path) == FileSystem.find(another_path) end
Source
# File lib/fakefs/file.rb, line 55 def self.join(*parts) RealFile.join(parts) end
Source
# File lib/fakefs/file.rb, line 268 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
Source
# File lib/fakefs/file.rb, line 303 def self.lstat(file) File::Stat.new(file, true) end
Source
# File lib/fakefs/file.rb, line 93 def self.mtime(path) if exist?(path) FileSystem.find(path).mtime else raise Errno::ENOENT end end
Source
# File lib/fakefs/file.rb, line 512 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
Source
# File lib/fakefs/file.rb, line 204 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
TODO: support open_key_args
Source
# File lib/fakefs/file.rb, line 83 def self.readable?(path) return false unless exist? path File.lstat(path).readable? end
Source
# File lib/fakefs/file.rb, line 218 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
Source
# File lib/fakefs/file.rb, line 198 def self.readlink(path) symlink = FileSystem.find(path) symlink.target end
Source
# File lib/fakefs/file.rb, line 763 def self.realdirpath(*args) RealFile.realdirpath(*args) end
Source
# File lib/fakefs/file.rb, line 726 def self.realpath(*args) RealFile.realpath(*args) end
Source
# File lib/fakefs/file.rb, line 242 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
Source
# File lib/fakefs/file.rb, line 130 def self.size(path) if directory?(path) 64 + (32 * FileSystem.find(path).entries.size) else read(path).bytesize end end
Source
# File lib/fakefs/file.rb, line 138 def self.size?(path) size(path) if exist?(path) && !size(path).zero? end
Source
# File lib/fakefs/file.rb, line 307 def self.split(path) RealFile.split(path) end
Source
# File lib/fakefs/file.rb, line 78 def sticky?(_path) false end
Assume nothing is sticky.
Source
# File lib/fakefs/file.rb, line 295 def self.symlink(source, dest) FileUtils.ln_s(source, dest) end
Source
# File lib/fakefs/file.rb, line 165 def self.symlink?(path) if path.respond_to? :entry path.is_a? FakeSymlink else FileSystem.find(path).is_a? FakeSymlink end end
Source
# File lib/fakefs/file.rb, line 344 def self.umask(*args) RealFile.umask(*args) end
Source
# File lib/fakefs/file.rb, line 117 def self.utime(atime, mtime, *paths) paths.each do |path| if exist?(path) FileSystem.find(path).atime = atime FileSystem.find(path).mtime = mtime else raise Errno::ENOENT end end paths.size end
Source
# File lib/fakefs/file.rb, line 88 def self.writable?(path) return false unless exist? path File.lstat(path).writable? end
Source
# File lib/fakefs/file.rb, line 769 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
Source
# File lib/fakefs/file.rb, line 142 def self.zero?(path) exist?(path) && size(path) == 0 end
Private Class Methods
Source
# File lib/fakefs/file.rb, line 938 def self.calculate_chmod_amt_for_mode(modes) valid_modes_to_numeric_vals = { 'r' => 0o4, 'w' => 0o2, 'x' => 0o1 } # if we give no modes, then we are removing all permission chmod_perm_num = 0o0 if modes != '' # make sure there are no invalid flags in the modes and that we discard duplicates as chmod does given_modes = modes.split('') given_modes = given_modes.uniq given_modes.each do |specific_mode| # ensure that the mode is valid unless valid_modes_to_numeric_vals.key? specific_mode raise ArgumentError, "Invalid `perm' symbol in file mode: #{specific_mode}" end chmod_perm_num += valid_modes_to_numeric_vals[specific_mode] end end chmod_perm_num end
given a list of modes [rwx] (a) ensure all modes are valid and (b) return the numeric value associated with the modes
Source
# File lib/fakefs/file.rb, line 811 def self.convert_symbolic_chmod_to_absolute(new_mode, current_mode) # mode always must be of form <GROUP1>=<FLAGS>,<GROUP2>=<FLAGS,... # e.g.: u=wr,go=x chmod_pairs = new_mode.split(',') # - duplicating groups is OK ( e.g.: 'ugouuoouu' is valid and is interpretted as 'ugo' ) # - duplicating modes is OK ( e.g.: 'wwwwwwwww' is interpreted as 'w' ) # - omitting the right hand side is interpretted as removing all permission # ( e.g.: 'ugo=' is really 'chmod 000' ) # - omitting the left hand side is interpretted as all groups ( e.g.: '=rwx' is really 'ugo=rwx' ) # - if we list a group more than once, we only apply the rightmost permissions # ( e.g.: 'ug=rx,g=x' is really 'u=r,g=x' ) # - we cannot list any flags that are not 'rwx' ( e.g.: converting 'ug=rwx' to 'ug=7' is invalid ) # or else an error is raised # - in the example above, the following error is raised: 'invalid `perm' symbol in file mode: 7 (ArgumentError)' # - we cannot put in any groups that are not 'ugo' ( e.g.: listing groups as 'uzg=x' is invalid ) # or else an error is raised # - in the example above, the following error is raised: 'invalid `who' symbol in file mode: z (ArgumentError)' valid_groups_to_numeric_vals = { 'u' => 0o100, 'g' => 0o10, 'o' => 0o1 } # make sure we preload the current group values. # chmod works by calculating new permissions based off of existing permissions current_groups_to_vals = { 0o100 => 0o0, 0o10 => 0o0, 0o1 => 0o0 } [0o100, 0o10, 0o1].each do |group_num| perm_amt = get_perms_for_group(current_mode, group_num) current_groups_to_vals[group_num] = perm_amt end chmod_pairs.each do |pair| # see if we are dealing with +/- ( granting or removing permissions ) or = ( assigning permissions ) # note that it IS valid to mix assignment and granting/revoking perissions ( things like u=wrx,g+x are valid ) assign_perms = '=' remove_perms = '-' add_perms = '+' assignment_mode = nil if pair.include? remove_perms assignment_mode = remove_perms elsif pair.include? add_perms assignment_mode = add_perms elsif pair.include? assign_perms assignment_mode = assign_perms end # if we can't find a mode, then raise an exception as real `chmod` would if assignment_mode.nil? raise ArgumentError, "Invalid file mode: #{mode}" end adding_removing_perms = [add_perms, remove_perms].include?(assignment_mode) groups = pair.rpartition(assignment_mode).first modes = pair.rpartition(assignment_mode).last # get the numeric chmod value associated with the symbolic entry chmod_perm_num = calculate_chmod_amt_for_mode modes # if we give no groups, then we are giving all groups if groups == '' if adding_removing_perms [0o100, 0o10, 0o1].each do |group_num| perm_amt = set_perms_for_group(current_groups_to_vals, group_num, assignment_mode, chmod_perm_num) current_groups_to_vals[group_num] = perm_amt end else [0o100, 0o10, 0o1].each do |group_num| current_groups_to_vals[group_num] = chmod_perm_num end end else # make sure there are no invalid flags in the groups and that we discard duplicates as chmod does given_groups = groups.split('') given_groups = given_groups.uniq given_groups.each do |specific_group| # ensure that the group is valid unless valid_groups_to_numeric_vals.key? specific_group raise ArgumentError, "Invalid `who' symbol in file mode: #{specific_group}" end # take the current chmod amt from earlier and associate that as the current chmod factor for the group # if we are adding or removing groups ( via +/- ) then we must make sure that we adjust # the current chmod perm number for the group group_num = valid_groups_to_numeric_vals[specific_group] adjusted_chmod = chmod_perm_num if adding_removing_perms adjusted_chmod = set_perms_for_group(current_groups_to_vals, group_num, assignment_mode, chmod_perm_num) end current_groups_to_vals[group_num] = adjusted_chmod end end end # return an octal chmod value for the value 0o100 * current_groups_to_vals[0o100] + 0o10 * current_groups_to_vals[0o10] + current_groups_to_vals[0o1] end
Source
# File lib/fakefs/file.rb, line 906 def self.get_perms_for_group(current_file_mode, group_num) # get the current recorded mode of the group and return it to the caller # note we don't shift for 'o' since that is the bottom 3 bits # note we multiply by 7 since the group num is 1, and octal represents digits 1-7 and we want all 3 bits current_group_mode = current_file_mode & (group_num * 7) if group_num == 0o100 current_group_mode >>= 6 elsif group_num == 0o10 current_group_mode >>= 3 end current_group_mode end
return the group mode for group num based off the provided current_file_mode
Source
# File lib/fakefs/file.rb, line 922 def self.set_perms_for_group(current_groups_to_vals, group_num, assignment_mode, chmod_perm_num) # get the current recorded mode of the group current_group_mode = current_groups_to_vals[group_num] # now that we have the current value of the group, add or remove bits accordingly if assignment_mode == '+' current_group_mode | chmod_perm_num elsif assignment_mode == '-' current_group_mode & ~chmod_perm_num else raise ArgumentError, "Unknown assignment mode #{assignment_mode}" end end
given the current chmod values for a file return the result of adding or removing chmod_perm_num from the requested groups permissions ( so performing <GROUP>+<PERMS> or <GROUP>-<PERMS>
Public Instance Methods
Source
# File lib/fakefs/file.rb, line 767 def advise(_advice, _offset = 0, _len = 0); end
Source
# File lib/fakefs/file.rb, line 753 def autoclose? @autoclose ? true : false end
Source
# File lib/fakefs/file.rb, line 730 def binmode? # File.open('test_mode', mode: 'w:binary').binmode? # => false @fmode & FMODE_BINMODE != 0 end
Source
# File lib/fakefs/file.rb, line 807 def birthtime self.class.birthtime(@path) end
Source
# File lib/fakefs/file.rb, line 700 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
Source
# File lib/fakefs/file.rb, line 712 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
Source
# File lib/fakefs/file.rb, line 735 def close_on_exec=(_bool) raise NotImplementedError end
Source
# File lib/fakefs/file.rb, line 739 def close_on_exec? raise NotImplementedError end
Source
# File lib/fakefs/file.rb, line 641 def is_a?(klass) RealFile.allocate.is_a?(klass) end
Source
# File lib/fakefs/file.rb, line 653 def read_nonblock raise NotImplementedError end
Source
# File lib/fakefs/file.rb, line 680 def readpartial(*) super end
Source
# File lib/fakefs/file.rb, line 665 def sysseek(position, whence = SEEK_SET) seek(position, whence) pos end
Source
# File lib/fakefs/file.rb, line 616 def write(*args) val = super(*args) @file.mtime = Time.now val end
Source
# File lib/fakefs/file.rb, line 676 def write_nonblock(*) raise NotImplementedError end
Private Instance Methods
Source
# File lib/fakefs/file.rb, line 1057 def check_file_existence! raise Errno::ENOENT, @path.to_s unless @file end
Source
# File lib/fakefs/file.rb, line 991 def create_fmode(oflags) # rb_io_oflags_fmode fmode = 0 case oflags & FILE_ACCESS_MODE when RealFile::RDONLY fmode = FMODE_READABLE when RealFile::WRONLY fmode = FMODE_WRITABLE when RealFile::RDWR fmode = FMODE_READWRITE end fmode |= FMODE_APPEND if (oflags & RealFile::APPEND) != 0 fmode |= FMODE_TRUNC if (oflags & RealFile::TRUNC) != 0 fmode |= FMODE_CREATE if (oflags & RealFile::CREAT) != 0 fmode |= FMODE_EXCL if (oflags & RealFile::EXCL) != 0 fmode |= FMODE_BINMODE if (oflags & RealFile::BINARY) != 0 fmode end
Source
# File lib/fakefs/file.rb, line 1071 def create_missing_file if @file raise Errno::EEXIST, @path.to_s if mode_in?(RealFile::EXCL) raise Errno::EISDIR, path.to_s if File.directory?(@path) return end dirname = RealFile.dirname @path unless dirname == '.' dir = FileSystem.find dirname raise Errno::ENOENT, path.to_s unless dir.is_a? FakeDir end @file = FileSystem.add(path, FakeFile.new) end
Create a missing file if the path is valid.
Source
# File lib/fakefs/file.rb, line 966 def extract_binmode(opts, fmode) textmode = opts[:textmode] unless textmode.nil? raise ArgumentError, "textmode specified twice" if fmode & FMODE_TEXTMODE != 0 raise ArgumentError, "both textmode and binmode specified" if fmode & FMODE_BINMODE != 0 # yep, false has no effect here, but still causes ArgumentError fmode |= FMODE_TEXTMODE if textmode end binmode = opts[:binmode] unless binmode.nil? raise ArgumentError, "binmode specified twice" if fmode & FMODE_BINMODE != 0 raise ArgumentError, "both textmode and binmode specified" if fmode & FMODE_TEXTMODE != 0 fmode |= FMODE_BINMODE if binmode end if fmode & FMODE_BINMODE != 0 && fmode & FMODE_TEXTMODE != 0 raise ArgumentError, "both textmode and binmode specified" end fmode end
split the private class method decleration so rubocop doesn’t complain the line is too long
Source
# File lib/fakefs/file.rb, line 1061 def file_creation_mode? mode_in?(RealFile::CREAT) end
Source
# File lib/fakefs/file.rb, line 1065 def mode_in?(mask) (@oflags & mask) != 0 end
Source
# File lib/fakefs/file.rb, line 1010 def parse_strmode_oflags(mode) # rb_io_modestr_fmode access_mode = mode[0] mode_modificators = mode[1..-1].split(':', 2).first fmode = TEXT_MODES[access_mode] raise ArgumentError, "invalid access mode #{mode}" unless fmode mode_modificators&.each_char do |m| case m when 'b' fmode |= FMODE_BINMODE when 't' fmode |= FMODE_TEXTMODE when '+' fmode |= FMODE_READWRITE when 'x' raise ArgumentError, "invalid access mode #{mode}" unless access_mode == 'w' fmode |= FMODE_EXCL else raise ArgumentError, "invalid access mode #{mode}" end end if (fmode & FMODE_BINMODE).nonzero? && (fmode & FMODE_TEXTMODE).nonzero? raise ArgumentError, "invalid access mode #{mode}" end # rb_io_fmode_oflags oflags = 0 case fmode & FMODE_READWRITE when FMODE_READABLE oflags |= RealFile::RDONLY when FMODE_WRITABLE oflags |= RealFile::WRONLY when FMODE_READWRITE oflags |= RealFile::RDWR end oflags |= RealFile::APPEND if (fmode & FMODE_APPEND).nonzero? oflags |= RealFile::TRUNC if (fmode & FMODE_TRUNC).nonzero? oflags |= RealFile::CREAT if (fmode & FMODE_CREATE).nonzero? oflags |= RealFile::EXCL if (fmode & FMODE_EXCL).nonzero? oflags |= RealFile::BINARY if (fmode & FMODE_BINMODE).nonzero? [oflags, fmode] end