memfs 0.4.1 → 0.4.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: 70a8628ef207a62b0e968c52b562a999eb9b17eb
4
+ data.tar.gz: da534038352ee4290851b8dc4f2f7aef7bed7cf5
5
+ SHA512:
6
+ metadata.gz: c47dc6fe5eb179d3ee6d4e1e439e714d19920af0d474fa6166c1c8d75eb0c6a9c37d5115cf9db627e1801e0318dcb077620f05c87387428698061282610541a5
7
+ data.tar.gz: 218c397cacf5071ea1f83cfa06b12b8420bfef293390c652066f5548f6f9b7e9fba78e6d19af76f6d73a59bf0939a3ffdbcb66f7b649a9073ce9406c04fd5da0
@@ -0,0 +1,29 @@
1
+ AlignParameters:
2
+ Enabled: false
3
+
4
+ Blocks:
5
+ Enabled: false
6
+
7
+ ClassLength:
8
+ Enabled: false
9
+
10
+ Documentation:
11
+ Enabled: false
12
+
13
+ DoubleNegation:
14
+ Enabled: false
15
+
16
+ EmptyLinesAroundBody:
17
+ Enabled: false
18
+
19
+ LineLength:
20
+ Enabled: false
21
+
22
+ PercentLiteralDelimiters:
23
+ Enabled: false
24
+
25
+ SpecialGlobalVars:
26
+ Enabled: false
27
+
28
+ TrivialAccessors:
29
+ Enabled: false
@@ -1,5 +1,12 @@
1
1
  # Changelog
2
2
 
3
+ ## HEAD
4
+
5
+ ## 0.4.2
6
+
7
+ * ADD: `File#external_encoding`
8
+ * FIX: Undefined local variable or method `fs' for MemFs::File
9
+
3
10
  ## 0.4.1
4
11
 
5
12
  * FIX: Support for 1.9.3 broken by File::FNM_EXTGLOB
data/Guardfile CHANGED
@@ -1,8 +1,7 @@
1
- # A sample Guardfile
2
- # More info at https://github.com/guard/guard#readme
3
-
4
- guard 'rspec' do
1
+ guard :rspec, cmd: 'bundle exec rspec', all_after_pass: true, all_on_start: true do
5
2
  watch(%r{^spec/.+_spec\.rb$})
6
- watch(%r{^lib/(.+)\.rb$}) { |m| "spec/lib/#{m[1]}_spec.rb" }
7
- watch('spec/spec_helper.rb') { "spec" }
3
+ watch(%r{^lib/(.+)\.rb$}) { |m| "spec/#{m[1]}_spec.rb" }
4
+
5
+ watch('lib/memfs/io.rb') { |m| 'spec/memfs/file_spec.rb' }
6
+ watch('spec/spec_helper.rb') { 'spec' }
8
7
  end
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # MemFs
1
+ ![MemFs Logo](https://raw.github.com/simonc/memfs/master/memfs.png)
2
2
 
3
3
  [![Gem Version](https://badge.fury.io/rb/memfs.png)](http://badge.fury.io/rb/memfs)
4
4
  [![Build Status](https://secure.travis-ci.org/simonc/memfs.png?branch=master)](http://travis-ci.org/simonc/memfs)
@@ -83,7 +83,7 @@ you `spec_helper.rb` file:
83
83
  ``` ruby
84
84
  Rspec.configure do |c|
85
85
  c.around(:each, memfs: true) do |example|
86
- MemFs.activate { example.run }
86
+ MemFs.activate { example.run }
87
87
  end
88
88
  end
89
89
  ```
@@ -93,7 +93,7 @@ And then write your specs like this:
93
93
  ``` ruby
94
94
  it "creates a file", memfs: true do
95
95
  subject.create_file('test.rb')
96
- expect(File.exists?('test.rb')).to be_true
96
+ expect(File.exists?('test.rb')).to be true
97
97
  end
98
98
  ```
99
99
 
@@ -107,7 +107,7 @@ describe FileCreator do
107
107
  it "creates a file" do
108
108
  MemFs.activate do
109
109
  subject.create_file('test.rb')
110
- expect(File.exists?('test.rb')).to be_true
110
+ expect(File.exists?('test.rb')).to be true
111
111
  end
112
112
  end
113
113
  end
@@ -126,7 +126,7 @@ describe FileCreator do
126
126
  describe '.create_file' do
127
127
  it "creates a file" do
128
128
  subject.create_file('test.rb')
129
- expect(File.exists?('test.rb')).to be_true
129
+ expect(File.exists?('test.rb')).to be true
130
130
  end
131
131
  end
132
132
  end
@@ -145,7 +145,7 @@ end
145
145
 
146
146
  ## Requirements
147
147
 
148
- * Ruby 2.0+
148
+ * Ruby 1.9.3 or newer
149
149
 
150
150
  ## Known issues
151
151
 
data/Rakefile CHANGED
@@ -4,7 +4,7 @@ require 'memfs'
4
4
 
5
5
  RSpec::Core::RakeTask.new(:spec)
6
6
 
7
- task :default => :spec
7
+ task default: :spec
8
8
 
9
9
  desc 'Compares a MemFs class to the original Ruby one ' \
10
10
  '(set CLASS to the compared class)'
@@ -36,3 +36,11 @@ task :compare do
36
36
  puts
37
37
  puts implemented_i_methods - original_i_methods
38
38
  end
39
+
40
+ task :console do
41
+ require 'irb'
42
+ require 'irb/completion'
43
+ require 'memfs'
44
+ ARGV.clear
45
+ IRB.start
46
+ end
@@ -16,8 +16,6 @@ require 'fileutils'
16
16
  # MemFs.deactivate!
17
17
  # # Everything back to normal
18
18
  module MemFs
19
- extend self
20
-
21
19
  # Keeps track of the original Ruby Dir class.
22
20
  OriginalDir = ::Dir
23
21
 
@@ -56,6 +54,7 @@ module MemFs
56
54
  ensure
57
55
  deactivate!
58
56
  end
57
+ module_function :activate
59
58
 
60
59
  # Activates the fake file system.
61
60
  #
@@ -76,12 +75,13 @@ module MemFs
76
75
  remove_const :Dir
77
76
  remove_const :File
78
77
 
79
- const_set :Dir, MemFs::Dir
78
+ const_set :Dir, MemFs::Dir
80
79
  const_set :File, MemFs::File
81
80
  end
82
81
 
83
82
  MemFs::FileSystem.instance.clear!
84
83
  end
84
+ module_function :activate!
85
85
 
86
86
  # Deactivates the fake file system.
87
87
  #
@@ -94,10 +94,11 @@ module MemFs
94
94
  remove_const :Dir
95
95
  remove_const :File
96
96
 
97
- const_set :Dir, MemFs::OriginalDir
97
+ const_set :Dir, MemFs::OriginalDir
98
98
  const_set :File, MemFs::OriginalFile
99
99
  end
100
100
  end
101
+ module_function :deactivate!
101
102
 
102
103
  # Creates a file and all its parent directories.
103
104
  #
@@ -114,4 +115,5 @@ module MemFs
114
115
  FileUtils.touch path
115
116
  end
116
117
  end
118
+ module_function :touch
117
119
  end
@@ -4,6 +4,7 @@ module MemFs
4
4
  class Dir
5
5
  extend FilesystemAccess
6
6
  include Enumerable
7
+ include FilesystemAccess
7
8
 
8
9
  attr_reader :pos
9
10
 
@@ -13,13 +14,11 @@ module MemFs
13
14
 
14
15
  def self.chdir(path, &block)
15
16
  fs.chdir path, &block
16
- return 0
17
+ 0
17
18
  end
18
19
 
19
20
  def self.chroot(path)
20
- unless Process.uid.zero?
21
- raise Errno::EPERM, path
22
- end
21
+ fail Errno::EPERM, path unless Process.uid.zero?
23
22
 
24
23
  dir = fs.find_directory!(path)
25
24
  dir.name = '/'
@@ -27,14 +26,14 @@ module MemFs
27
26
  0
28
27
  end
29
28
 
30
- def self.entries(dirname, opts = {})
29
+ def self.entries(dirname, _opts = {})
31
30
  fs.entries(dirname)
32
31
  end
33
32
 
34
33
  def self.exists?(path)
35
34
  File.directory?(path)
36
35
  end
37
- class << self; alias :exist? :exists?; end
36
+ class << self; alias_method :exist?, :exists?; end
38
37
 
39
38
  def self.foreach(dirname, &block)
40
39
  return to_enum(__callee__, dirname) unless block
@@ -45,19 +44,20 @@ module MemFs
45
44
  def self.getwd
46
45
  fs.getwd
47
46
  end
48
- class << self; alias :pwd :getwd; end
47
+ class << self; alias_method :pwd, :getwd; end
49
48
 
50
49
  def self.glob(patterns, flags = 0)
51
50
  patterns = [*patterns]
52
51
  list = fs.paths.select do |path|
53
- patterns.any? do |pattern|
54
- File.fnmatch?(pattern, path, flags | GLOB_FLAGS)
55
- end
56
- end
52
+ patterns.any? do |pattern|
53
+ File.fnmatch?(pattern, path, flags | GLOB_FLAGS)
54
+ end
55
+ end
57
56
  # FIXME: ugly special case for /* and /
58
57
  list.delete('/') if patterns.first == '/*'
59
58
  return list unless block_given?
60
- list.each { |path| yield path } and nil
59
+ list.each { |path| yield path }
60
+ nil
61
61
  end
62
62
 
63
63
  def self.home(*args)
@@ -89,8 +89,8 @@ module MemFs
89
89
  end
90
90
 
91
91
  class << self
92
- alias :delete :rmdir
93
- alias :unlink :rmdir
92
+ alias_method :delete, :rmdir
93
+ alias_method :unlink, :rmdir
94
94
  end
95
95
 
96
96
  def initialize(path)
@@ -101,9 +101,7 @@ module MemFs
101
101
  end
102
102
 
103
103
  def close
104
- if state == :closed
105
- fail IOError, 'closed directory'
106
- end
104
+ fail IOError, 'closed directory' if state == :closed
107
105
  self.state = :closed
108
106
  end
109
107
 
@@ -115,7 +113,7 @@ module MemFs
115
113
  def path
116
114
  entry.path
117
115
  end
118
- alias :to_path :path
116
+ alias_method :to_path, :path
119
117
 
120
118
  def pos=(position)
121
119
  seek(position)
@@ -135,9 +133,7 @@ module MemFs
135
133
  end
136
134
 
137
135
  def seek(position)
138
- if (0..max_seek).cover?(position)
139
- @pos = position
140
- end
136
+ @pos = position if (0..max_seek).cover?(position)
141
137
  self
142
138
  end
143
139
 
@@ -50,8 +50,8 @@ module MemFs
50
50
  @dev ||= rand(1000)
51
51
  end
52
52
 
53
- def find(path)
54
- raise Errno::ENOTDIR, self.path
53
+ def find(_path)
54
+ fail Errno::ENOTDIR, path
55
55
  end
56
56
 
57
57
  def initialize(path = nil)
@@ -1,4 +1,4 @@
1
- require "delegate"
1
+ require 'delegate'
2
2
 
3
3
  module MemFs
4
4
  module Fake
@@ -20,7 +20,8 @@ module MemFs
20
20
  def puts(*strings)
21
21
  strings.each do |str|
22
22
  @string << str
23
- @string << $/ unless str.end_with?($/)
23
+ next if str.end_with?($/)
24
+ @string << $/
24
25
  end
25
26
  end
26
27
 
@@ -1,25 +1,31 @@
1
1
  require 'forwardable'
2
2
  require 'memfs/filesystem_access'
3
+ require 'memfs/io'
3
4
 
4
5
  module MemFs
5
6
  class File
6
7
  extend FilesystemAccess
7
8
  extend SingleForwardable
9
+ extend IO::ClassMethods
10
+
8
11
  include Enumerable
9
12
  include FilesystemAccess
10
13
  include OriginalFile::Constants
14
+ include IO::InstanceMethods
11
15
 
12
16
  MODE_MAP = {
13
17
  'r' => RDONLY,
14
18
  'r+' => RDWR,
15
- 'w' => CREAT|TRUNC|WRONLY,
16
- 'w+' => CREAT|TRUNC|RDWR,
17
- 'a' => CREAT|APPEND|WRONLY,
18
- 'a+' => CREAT|APPEND|RDWR
19
+ 'w' => CREAT | TRUNC | WRONLY,
20
+ 'w+' => CREAT | TRUNC | RDWR,
21
+ 'a' => CREAT | APPEND | WRONLY,
22
+ 'a+' => CREAT | APPEND | RDWR
19
23
  }
20
24
 
21
25
  SUCCESS = 0
22
26
 
27
+ @umask = nil
28
+
23
29
  def_delegators :original_file_class,
24
30
  :basename,
25
31
  :dirname,
@@ -45,8 +51,6 @@ module MemFs
45
51
  :setuid?,
46
52
  :socket?,
47
53
  :sticky?,
48
- :world_readable?,
49
- :world_writable?,
50
54
  :writable?,
51
55
  :writable_real?,
52
56
  :zero?
@@ -56,6 +60,15 @@ module MemFs
56
60
  end # end
57
61
  end
58
62
 
63
+ [
64
+ :world_readable?,
65
+ :world_writable?
66
+ ].each do |query_method|
67
+ define_singleton_method(query_method) do |path| # def directory?(path)
68
+ stat_query(path, query_method, false) # stat_query(path, :directory?, false)
69
+ end # end
70
+ end
71
+
59
72
  def self.absolute_path(path, dir_string = fs.pwd)
60
73
  original_file_class.absolute_path(path, dir_string)
61
74
  end
@@ -84,7 +97,7 @@ module MemFs
84
97
  def self.exists?(path)
85
98
  !!fs.find(path)
86
99
  end
87
- class << self; alias :exist? :exists?; end
100
+ class << self; alias_method :exist?, :exists?; end
88
101
 
89
102
  def self.expand_path(file_name, dir_string = fs.pwd)
90
103
  original_file_class.expand_path(file_name, dir_string)
@@ -94,7 +107,7 @@ module MemFs
94
107
  fs.find!(path) && lstat(path).ftype
95
108
  end
96
109
 
97
- class << self; alias :fnmatch? :fnmatch; end
110
+ class << self; alias_method :fnmatch?, :fnmatch; end
98
111
 
99
112
  def self.identical?(path1, path2)
100
113
  fs.find!(path1).dereferenced === fs.find!(path2).dereferenced
@@ -126,7 +139,7 @@ module MemFs
126
139
  end
127
140
 
128
141
  def self.open(filename, mode = RDONLY, *perm_and_opt)
129
- file = self.new(filename, mode, *perm_and_opt)
142
+ file = new(filename, mode, *perm_and_opt)
130
143
 
131
144
  if block_given?
132
145
  yield file
@@ -137,21 +150,6 @@ module MemFs
137
150
  file.close if file && block_given?
138
151
  end
139
152
 
140
- def self.read(path, *args)
141
- options = args.last.is_a?(Hash) ? args.pop : {}
142
- options = { mode: RDONLY, encoding: nil, open_args: nil }.merge(options)
143
- open_args = options[:open_args] ||
144
- [options[:mode], encoding: options[:encoding]]
145
-
146
- length, offset = args
147
-
148
- file = open(path, *open_args)
149
- file.seek(offset || 0)
150
- file.read(length)
151
- ensure
152
- file.close if file
153
- end
154
-
155
153
  def self.readlink(path)
156
154
  fs.find!(path).target
157
155
  end
@@ -179,7 +177,11 @@ module MemFs
179
177
 
180
178
  def self.size?(path)
181
179
  file = fs.find(path)
182
- file && file.size > 0 && file.size
180
+ if file && file.size > 0
181
+ file.size
182
+ else
183
+ false
184
+ end
183
185
  end
184
186
 
185
187
  def self.stat(path)
@@ -214,7 +216,7 @@ module MemFs
214
216
  end
215
217
  paths.size
216
218
  end
217
- class << self; alias :delete :unlink; end
219
+ class << self; alias_method :delete, :unlink; end
218
220
 
219
221
  def self.utime(atime, mtime, *file_names)
220
222
  file_names.each do |file_name|
@@ -226,13 +228,17 @@ module MemFs
226
228
 
227
229
  attr_reader :path
228
230
 
229
- def initialize(filename, mode = RDONLY, perm = nil, opt = nil)
230
- unless opt.nil? || opt.is_a?(Hash)
231
- raise ArgumentError, "wrong number of arguments (4 for 1..3)"
231
+ def initialize(filename, mode = File::RDONLY, *perm_and_or_opt)
232
+ opt = perm_and_or_opt.last.is_a?(Hash) ? perm_and_or_opt.pop : {}
233
+ perm = perm_and_or_opt.shift
234
+ if perm_and_or_opt.size > 0
235
+ fail ArgumentError, 'wrong number of arguments (4 for 1..3)'
232
236
  end
233
237
 
234
238
  @path = filename
239
+ @external_encoding = opt[:external_encoding] && Encoding.find(opt[:external_encoding])
235
240
 
241
+ self.closed = false
236
242
  self.opening_mode = str_to_mode_int(mode)
237
243
 
238
244
  fs.touch(filename) if create_file?
@@ -242,6 +248,10 @@ module MemFs
242
248
  entry.content.clear if truncate_file?
243
249
  end
244
250
 
251
+ def atime
252
+ File.atime(path)
253
+ end
254
+
245
255
  def chmod(mode_int)
246
256
  fs.chmod(mode_int, path)
247
257
  SUCCESS
@@ -252,76 +262,35 @@ module MemFs
252
262
  SUCCESS
253
263
  end
254
264
 
255
- def close
256
- self.closed = true
265
+ def ctime
266
+ File.ctime(path)
257
267
  end
258
268
 
259
- def closed?
260
- closed
269
+ def flock(*)
270
+ SUCCESS
261
271
  end
262
272
 
263
- def each(sep = $/, &block)
264
- return to_enum(__callee__) unless block_given?
265
- fail IOError, 'not opened for reading' unless readable?
266
- content.each_line(sep) { |line| block.call(line) }
267
- self
273
+ def mtime
274
+ File.mtime(path)
268
275
  end
269
276
 
270
277
  def lstat
271
278
  File.lstat(path)
272
279
  end
273
280
 
274
- def pos
275
- entry.pos
276
- end
277
-
278
- def puts(text)
279
- raise IOError, 'not opened for writing' unless writable?
280
-
281
- content.puts text
282
- end
283
-
284
- def read(length = nil, buffer = '')
285
- default = length ? nil : ''
286
- content.read(length, buffer) || default
287
- end
288
-
289
- def seek(amount, whence = IO::SEEK_SET)
290
- new_pos = case whence
291
- when IO::SEEK_CUR then entry.pos + amount
292
- when IO::SEEK_END then content.to_s.length + amount
293
- when IO::SEEK_SET then amount
294
- end
295
-
296
- if new_pos.nil? || new_pos < 0
297
- raise Errno::EINVAL, path
298
- end
299
-
300
- entry.pos = new_pos and 0
301
- end
302
-
303
281
  def size
304
282
  entry.size
305
283
  end
306
284
 
307
- def stat
308
- File.stat(path)
309
- end
310
-
311
- def write(string)
312
- raise IOError, 'not opened for writing' unless writable?
313
-
314
- content.write(string.to_s)
285
+ def truncate(integer)
286
+ File.truncate(path, integer)
315
287
  end
316
288
 
317
289
  private
318
290
 
319
- attr_accessor :closed,
320
- :entry,
321
- :opening_mode
322
-
323
291
  def self.dereference_name(path)
324
- if entry = fs.find(path)
292
+ entry = fs.find(path)
293
+ if entry
325
294
  entry.dereferenced_name
326
295
  else
327
296
  basename(path)
@@ -349,47 +318,16 @@ module MemFs
349
318
  end
350
319
  private_class_method :original_file_class
351
320
 
352
- def self.stat_query(path, query)
353
- fs.find(path) && stat(path).public_send(query)
321
+ def self.stat_query(path, query, force_boolean = true)
322
+ response = fs.find(path) && stat(path).public_send(query)
323
+ force_boolean ? !!(response) : response
354
324
  end
355
325
  private_class_method :stat_query
356
326
 
357
327
  def self.lstat_query(path, query)
358
- fs.find(path) && lstat(path).public_send(query)
328
+ response = fs.find(path) && lstat(path).public_send(query)
329
+ !!(response)
359
330
  end
360
331
  private_class_method :lstat_query
361
-
362
- def content
363
- entry.content
364
- end
365
-
366
- def str_to_mode_int(mode)
367
- return mode unless mode.is_a?(String)
368
-
369
- unless mode =~ /\A([rwa]\+?)([bt])?\z/
370
- raise ArgumentError, "invalid access mode #{mode}"
371
- end
372
-
373
- mode_str = $~[1]
374
- MODE_MAP[mode_str]
375
- end
376
-
377
- def create_file?
378
- (opening_mode & File::CREAT).nonzero?
379
- end
380
-
381
- def readable?
382
- (opening_mode & File::RDWR).nonzero? ||
383
- (opening_mode | File::RDONLY).zero?
384
- end
385
-
386
- def truncate_file?
387
- (opening_mode & File::TRUNC).nonzero?
388
- end
389
-
390
- def writable?
391
- (opening_mode & File::WRONLY).nonzero? ||
392
- (opening_mode & File::RDWR).nonzero?
393
- end
394
332
  end
395
333
  end