virtfs 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (91) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +18 -0
  3. data/.rspec +2 -0
  4. data/.travis.yml +8 -0
  5. data/Gemfile +4 -0
  6. data/LICENSE.txt +22 -0
  7. data/README.md +154 -0
  8. data/Rakefile +5 -0
  9. data/lib/virtfs-nativefs-thick.rb +1 -0
  10. data/lib/virtfs-nativefs-thin.rb +1 -0
  11. data/lib/virtfs.rb +38 -0
  12. data/lib/virtfs/activation.rb +97 -0
  13. data/lib/virtfs/block_io.rb +140 -0
  14. data/lib/virtfs/byte_range.rb +71 -0
  15. data/lib/virtfs/context.rb +300 -0
  16. data/lib/virtfs/context_manager.rb +175 -0
  17. data/lib/virtfs/context_switch_class_methods.rb +96 -0
  18. data/lib/virtfs/delegate_module.rb +40 -0
  19. data/lib/virtfs/dir_instance_delegate.rb +3 -0
  20. data/lib/virtfs/exception.rb +13 -0
  21. data/lib/virtfs/file_instance_delegate.rb +3 -0
  22. data/lib/virtfs/file_modes_and_options.rb +293 -0
  23. data/lib/virtfs/find_class_methods.rb +106 -0
  24. data/lib/virtfs/io_buffer.rb +133 -0
  25. data/lib/virtfs/io_instance_delegate.rb +3 -0
  26. data/lib/virtfs/kernel.rb +146 -0
  27. data/lib/virtfs/nativefs/thick.rb +30 -0
  28. data/lib/virtfs/nativefs/thick/dir_class_methods.rb +38 -0
  29. data/lib/virtfs/nativefs/thick/file_class_methods.rb +178 -0
  30. data/lib/virtfs/nativefs/thin.rb +32 -0
  31. data/lib/virtfs/nativefs/thin/dir.rb +30 -0
  32. data/lib/virtfs/nativefs/thin/dir_class_methods.rb +41 -0
  33. data/lib/virtfs/nativefs/thin/file.rb +112 -0
  34. data/lib/virtfs/nativefs/thin/file_class_methods.rb +181 -0
  35. data/lib/virtfs/protofs/protofs.rb +7 -0
  36. data/lib/virtfs/protofs/protofs_base.rb +12 -0
  37. data/lib/virtfs/protofs/protofs_dir.rb +13 -0
  38. data/lib/virtfs/protofs/protofs_dir_class.rb +31 -0
  39. data/lib/virtfs/protofs/protofs_file.rb +27 -0
  40. data/lib/virtfs/protofs/protofs_file_class.rb +136 -0
  41. data/lib/virtfs/stat.rb +100 -0
  42. data/lib/virtfs/thin_dir_delegator.rb +79 -0
  43. data/lib/virtfs/thin_file_delegator.rb +77 -0
  44. data/lib/virtfs/thin_io_delegator_methods.rb +301 -0
  45. data/lib/virtfs/thin_io_delegator_methods_bufferio.rb +337 -0
  46. data/lib/virtfs/v_dir.rb +238 -0
  47. data/lib/virtfs/v_file.rb +480 -0
  48. data/lib/virtfs/v_io.rb +243 -0
  49. data/lib/virtfs/v_pathname.rb +128 -0
  50. data/lib/virtfs/version.rb +3 -0
  51. data/spec/activate_spec.rb +202 -0
  52. data/spec/chroot_spec.rb +120 -0
  53. data/spec/context_manager_class_spec.rb +246 -0
  54. data/spec/context_manager_instance_spec.rb +255 -0
  55. data/spec/context_spec.rb +335 -0
  56. data/spec/data/UTF-16LE-data.txt +0 -0
  57. data/spec/data/UTF-8-data.txt +212 -0
  58. data/spec/dir_class_spec.rb +506 -0
  59. data/spec/dir_instance_spec.rb +208 -0
  60. data/spec/file_class_spec.rb +2106 -0
  61. data/spec/file_instance_spec.rb +154 -0
  62. data/spec/file_modes_and_options_spec.rb +1556 -0
  63. data/spec/find_spec.rb +142 -0
  64. data/spec/io_bufferio_size_shared_examples.rb +371 -0
  65. data/spec/io_bufferio_size_spec.rb +861 -0
  66. data/spec/io_bufferio_spec.rb +801 -0
  67. data/spec/io_class_spec.rb +145 -0
  68. data/spec/io_instance_spec.rb +516 -0
  69. data/spec/kernel_spec.rb +285 -0
  70. data/spec/mount_spec.rb +186 -0
  71. data/spec/nativefs_local_root_spec.rb +132 -0
  72. data/spec/path_spec.rb +39 -0
  73. data/spec/spec_helper.rb +126 -0
  74. data/tasks/rspec.rake +3 -0
  75. data/tasks/yard.rake +7 -0
  76. data/test/UTF-8-demo.txt +212 -0
  77. data/test/bench.rb +18 -0
  78. data/test/bio_internal_test.rb +45 -0
  79. data/test/delegate_io.rb +31 -0
  80. data/test/delegate_module.rb +62 -0
  81. data/test/encode_test.rb +42 -0
  82. data/test/enoent_test.rb +30 -0
  83. data/test/namespace_test.rb +42 -0
  84. data/test/read_block_valid_encoding.rb +44 -0
  85. data/test/read_test.rb +78 -0
  86. data/test/stream_readers.rb +46 -0
  87. data/test/utf-16-demo.txt +0 -0
  88. data/test/utf8_to_utf16.rb +77 -0
  89. data/test/wrapper_test.rb +34 -0
  90. data/virtfs.gemspec +29 -0
  91. metadata +230 -0
@@ -0,0 +1,120 @@
1
+ require 'spec_helper'
2
+
3
+ describe "VirtFS.dir_chroot (#{$fs_interface} interface)" do
4
+ before(:all) do
5
+ @full_path = VfsRealFile.expand_path(__FILE__)
6
+ @this_dir = VfsRealFile.expand_path(__dir__)
7
+ @root = File::SEPARATOR
8
+
9
+ @new_root = VfsRealFile.expand_path(VfsRealFile.join(__dir__, ".."))
10
+ @new_this_dir = VfsRealFile.expand_path(VfsRealFile.join("/", VfsRealFile.basename(__dir__)))
11
+ @new_full_path = VfsRealFile.expand_path(VfsRealFile.join(@new_this_dir, VfsRealFile.basename(__FILE__)))
12
+ end
13
+
14
+ before(:each) do
15
+ reset_context
16
+ @native_fs = nativefs_class.new
17
+ VirtFS.mount(@native_fs, @root)
18
+ end
19
+
20
+ describe "Dir.chroot" do
21
+ it "should raise Errno::ENOENT when directory does exist" do
22
+ expect do
23
+ VirtFS::VDir.chroot("/not_a_dir/foo.d")
24
+ end.to raise_error(
25
+ Errno::ENOENT, /No such file or directory/
26
+ )
27
+ end
28
+
29
+ it "should return 0 on success" do
30
+ expect(VirtFS::VDir.chroot(@this_dir)).to eq(0)
31
+ end
32
+
33
+ it "should set the value of root accordingly" do
34
+ VirtFS::VDir.chroot(@new_root)
35
+ expect(VirtFS.root).to eq(@new_root)
36
+ end
37
+
38
+ it "should set the current directory to '/'" do
39
+ VirtFS::VDir.chroot(@new_root)
40
+ expect(VirtFS::VDir.getwd).to eq(File::SEPARATOR)
41
+ end
42
+
43
+ it "should find directory through new full path" do
44
+ VirtFS::VDir.chroot(@new_root)
45
+ expect(VirtFS::VDir.exist?(@new_this_dir)).to be true
46
+ end
47
+
48
+ it "should find file through new full path" do
49
+ VirtFS::VDir.chroot(@new_root)
50
+ expect(VirtFS::VFile.exist?(@new_full_path)).to be true
51
+ end
52
+ end
53
+
54
+ describe "Dir.chdir" do
55
+ before(:all) do
56
+ @parent_dir = @new_root
57
+ @child_dir = @this_dir
58
+ @rel_child_dir_name = VfsRealFile.basename(@child_dir)
59
+ @abs_child_dir_name = VfsRealFile.join("/", @rel_child_dir_name)
60
+ end
61
+
62
+ it "should raise Errno::ENOENT when directory does exist under current root" do
63
+ VirtFS::VDir.chroot(@child_dir)
64
+ expect do
65
+ VirtFS::VDir.chdir(@parent_dir)
66
+ end.to raise_error(
67
+ Errno::ENOENT, /No such file or directory/
68
+ )
69
+ end
70
+
71
+ it "should cd to absolute path based on new root" do
72
+ VirtFS::VDir.chroot(@parent_dir)
73
+ VirtFS::VDir.chdir(@abs_child_dir_name)
74
+ expect(VirtFS::VDir.getwd).to eq(@abs_child_dir_name)
75
+ end
76
+
77
+ it "should cd to relative path based on new root" do
78
+ VirtFS::VDir.chroot(@parent_dir)
79
+ VirtFS::VDir.chdir(@rel_child_dir_name)
80
+ expect(VirtFS::VDir.getwd).to eq(@abs_child_dir_name)
81
+ end
82
+
83
+ it "should not permit traversal above root" do
84
+ VirtFS::VDir.chroot(@parent_dir)
85
+ VirtFS::VDir.chdir("..")
86
+ expect(VirtFS::VDir.getwd).to eq("/")
87
+ VirtFS::VDir.chdir(VfsRealFile.join("..", ".."))
88
+ expect(VirtFS::VDir.getwd).to eq("/")
89
+ VirtFS::VDir.chdir(VfsRealFile.join("..", "..", ".."))
90
+ expect(VirtFS::VDir.getwd).to eq("/")
91
+ end
92
+
93
+ it "should traverse up to root, then back down" do
94
+ VirtFS::VDir.chroot(@parent_dir)
95
+ VirtFS::VDir.chdir(VfsRealFile.join("..", "..", "..", @rel_child_dir_name))
96
+ expect(VirtFS::VDir.getwd).to eq(@abs_child_dir_name)
97
+ end
98
+ end
99
+
100
+ describe "Dir.glob" do
101
+ it "should enumerate the same file names as the standard Dir.glob - simple glob" do
102
+ VirtFS::VDir.chroot(@new_root)
103
+ VfsRealDir.chdir(@new_root) do # for VfsRealDir.glob
104
+ expect(VirtFS::VDir.glob("*")).to match_array(VfsRealDir.glob("*"))
105
+ expect(VirtFS::VDir.glob("*/*.rb")).to match_array(VfsRealDir.glob("*/*.rb"))
106
+ end
107
+ end
108
+
109
+ it "should enumerate the same file names as the standard Dir.glob - relative glob" do
110
+ VirtFS::VDir.chroot(@new_root)
111
+ VfsRealDir.chdir(@new_root) do # for VfsRealDir.glob
112
+ # We're at root, so the ".." will keep us at root.
113
+ v_results = VirtFS::VDir.glob("../**/*.rb").collect { |f| VfsRealFile.basename(f) }.sort
114
+ # We're not at root in the real FS, so omitting the ".." should result in the same files.
115
+ r_results = VfsRealDir.glob("**/*.rb").collect { |f| VfsRealFile.basename(f) }.sort
116
+ expect(v_results).to eq(r_results)
117
+ end
118
+ end
119
+ end
120
+ end
@@ -0,0 +1,246 @@
1
+ require 'spec_helper'
2
+
3
+ describe VirtFS, " - context manager class operations (#{$fs_interface} interface)" do
4
+ before(:all) do
5
+ @root = File::SEPARATOR
6
+ end
7
+
8
+ before(:each) do
9
+ reset_context
10
+ end
11
+
12
+ context "Before any FS operations" do
13
+ describe "context_manager.managers" do
14
+ it "should return a Hash" do
15
+ cm_hash = VirtFS.context_manager.managers
16
+ expect(cm_hash).to be_kind_of(Hash)
17
+ end
18
+
19
+ it "should return an empty hash before any operations" do
20
+ cm_hash = VirtFS.context_manager.managers
21
+ expect(cm_hash.empty?).to be true
22
+ end
23
+ end
24
+
25
+ describe "context_manager.current!" do
26
+ it "should raise VirtFS::NoContextError when there's no context for the ThreadGroup" do
27
+ expect do
28
+ VirtFS.context_manager.current!
29
+ end.to raise_exception(VirtFS::NoContextError, /No filesystem context defined for thread group:/)
30
+ end
31
+ end
32
+
33
+ describe "context!" do
34
+ it "should raise VirtFS::NoContextError when there's no context for the ThreadGroup" do
35
+ expect do
36
+ VirtFS.context!
37
+ end.to raise_exception(VirtFS::NoContextError, /No filesystem context defined for thread group:/)
38
+ end
39
+ end
40
+
41
+ describe "context_manager.current" do
42
+ it "should return a ContextManager bound to our ThreadGroup" do
43
+ cmanager = VirtFS.context_manager.current
44
+ expect(cmanager.thread_group).to eq(Thread.current.group)
45
+ end
46
+ end
47
+
48
+ describe "context" do
49
+ it "should return a Context bound to our ThreadGroup" do
50
+ context = VirtFS.context
51
+ expect(context).to be_kind_of(VirtFS::Context)
52
+ end
53
+ end
54
+
55
+ describe "context_manager.manager_for" do
56
+ it "should raise ArgumentError when not passed a ThreadGroup object" do
57
+ expect do
58
+ VirtFS.context_manager.manager_for(nil)
59
+ end.to raise_exception(ArgumentError, "value must be a ThreadGroup object")
60
+ end
61
+
62
+ it "should return nil when given an unused ThreadGroup" do
63
+ expect(VirtFS.context_manager.manager_for(ThreadGroup.new)).to be nil
64
+ end
65
+
66
+ it "should return nil when given our ThreadGroup" do
67
+ expect(VirtFS.context_manager.manager_for(Thread.current.group)).to be nil
68
+ end
69
+ end
70
+
71
+ describe "context_manager.new_manager_for" do
72
+ it "should raise ArgumentError when not passed a ThreadGroup object" do
73
+ expect do
74
+ VirtFS.context_manager.new_manager_for(nil)
75
+ end.to raise_exception(ArgumentError, "value must be a ThreadGroup object")
76
+ end
77
+
78
+ it "should return a ContextManager when given an unused ThreadGroup" do
79
+ expect(VirtFS.context_manager.new_manager_for(ThreadGroup.new)).to be_kind_of(VirtFS::ContextManager)
80
+ end
81
+
82
+ it "should return a ContextManager when given our ThreadGroup" do
83
+ expect(VirtFS.context_manager.new_manager_for(Thread.current.group)).to be_kind_of(VirtFS::ContextManager)
84
+ end
85
+
86
+ it "should return a ContextManager bound to a new ThreadGroup" do
87
+ tgroup = ThreadGroup.new
88
+ cmanager = VirtFS.context_manager.new_manager_for(tgroup)
89
+ expect(cmanager.thread_group).to eq(tgroup)
90
+ end
91
+
92
+ it "should return a ContextManager bound to our ThreadGroup" do
93
+ tgroup = Thread.current.group
94
+ cmanager = VirtFS.context_manager.new_manager_for(tgroup)
95
+ expect(cmanager.thread_group).to eq(tgroup)
96
+ end
97
+
98
+ it "new ContextManager should be retrievable by ThreadGroup" do
99
+ tgroup = Thread.current.group
100
+ cmanager = VirtFS.context_manager.new_manager_for(tgroup)
101
+ expect(VirtFS.context_manager.manager_for(tgroup)).to eq(cmanager)
102
+ end
103
+ end
104
+
105
+ describe "context_manager.remove_manager_for" do
106
+ it "should raise ArgumentError when not passed a ThreadGroup object" do
107
+ expect do
108
+ VirtFS.context_manager.remove_manager_for(nil)
109
+ end.to raise_exception(ArgumentError, "value must be a ThreadGroup object")
110
+ end
111
+
112
+ it "should return nil when given an unused ThreadGroup" do
113
+ expect(VirtFS.context_manager.remove_manager_for(ThreadGroup.new)).to be nil
114
+ end
115
+
116
+ it "should return nil when given our ThreadGroup" do
117
+ expect(VirtFS.context_manager.remove_manager_for(Thread.current.group)).to be nil
118
+ end
119
+ end
120
+ end
121
+
122
+ context "With root mounted by main thread/thread_group" do
123
+ before(:each) do
124
+ @native_fs = nativefs_class.new
125
+ VirtFS.mount(@native_fs, @root)
126
+ end
127
+
128
+ describe "context_manager.managers" do
129
+ it "should return a Hash" do
130
+ cm_hash = VirtFS.context_manager.managers
131
+ expect(cm_hash).to be_kind_of(Hash)
132
+ end
133
+
134
+ it "should return a Hash with one entry" do
135
+ cm_hash = VirtFS.context_manager.managers
136
+ expect(cm_hash.length).to eq(1)
137
+ end
138
+
139
+ it "should contain a ContextManager" do
140
+ cm = VirtFS.context_manager.managers.values.first
141
+ expect(cm).to be_kind_of(VirtFS::ContextManager)
142
+ end
143
+
144
+ it "should contain a ContextManager bound to the current ThreadGroup" do
145
+ cm = VirtFS.context_manager.managers.values.first
146
+ expect(cm.thread_group).to eq(Thread.current.group)
147
+ end
148
+ end
149
+
150
+ describe "context_manager_for" do
151
+ it "should raise ArgumentError when not passed a ThreadGroup object" do
152
+ expect do
153
+ VirtFS.context_manager.manager_for(nil)
154
+ end.to raise_exception(ArgumentError, "value must be a ThreadGroup object")
155
+ end
156
+
157
+ it "should return nil when given an unused ThreadGroup" do
158
+ expect(VirtFS.context_manager.manager_for(ThreadGroup.new)).to be nil
159
+ end
160
+
161
+ it "should return a ContextManager when given our ThreadGroup" do
162
+ cm = VirtFS.context_manager.manager_for(Thread.current.group)
163
+ expect(cm).to be_kind_of(VirtFS::ContextManager)
164
+ expect(cm.thread_group).to eq(Thread.current.group)
165
+ end
166
+ end
167
+ end
168
+
169
+ context "With root mounted by different thread groups" do
170
+ before(:each) do
171
+ @thread_groups = [ThreadGroup.new, ThreadGroup.new, ThreadGroup.new]
172
+ @thread_groups.each_with_index do |tg, i|
173
+ tg.add(Thread.current)
174
+ native_fs = nativefs_class.new
175
+ native_fs.name = "FS-#{i}"
176
+ VirtFS.mount(native_fs, @root)
177
+ end
178
+ end
179
+
180
+ after(:each) do
181
+ ThreadGroup::Default.add(Thread.current)
182
+ end
183
+
184
+ describe "context_manager.managers" do
185
+ it "should return a Hash" do
186
+ cm_hash = VirtFS.context_manager.managers
187
+ expect(cm_hash).to be_kind_of(Hash)
188
+ end
189
+
190
+ it "should return a hash of the expected length" do
191
+ cm_hash = VirtFS.context_manager.managers
192
+ expect(cm_hash.length).to eq(@thread_groups.length)
193
+ end
194
+
195
+ it "hash should contain one entry per thread group" do
196
+ cm_hash = VirtFS.context_manager.managers
197
+ @thread_groups.each do |tg|
198
+ cm = cm_hash[tg]
199
+ expect(cm).to be_kind_of(VirtFS::ContextManager)
200
+ expect(cm.thread_group).to eq(tg)
201
+ end
202
+ end
203
+ end
204
+
205
+ describe "context_manager.manager_for" do
206
+ it "should raise ArgumentError when not passed a ThreadGroup object" do
207
+ expect do
208
+ VirtFS.context_manager.manager_for(nil)
209
+ end.to raise_exception(ArgumentError, "value must be a ThreadGroup object")
210
+ end
211
+
212
+ it "should return nil when given an unused ThreadGroup" do
213
+ expect(VirtFS.context_manager.manager_for(ThreadGroup.new)).to be nil
214
+ end
215
+
216
+ it "should return a ContextManager when given each ThreadGroup" do
217
+ @thread_groups.each do |tg|
218
+ cm = VirtFS.context_manager.manager_for(tg)
219
+ expect(cm).to be_kind_of(VirtFS::ContextManager)
220
+ expect(cm.thread_group).to eq(tg)
221
+ end
222
+ end
223
+ end
224
+
225
+ describe "context_manager.remove_manager_for" do
226
+ it "should raise ArgumentError when not passed a ThreadGroup object" do
227
+ expect do
228
+ VirtFS.context_manager.remove_manager_for(nil)
229
+ end.to raise_exception(ArgumentError, "value must be a ThreadGroup object")
230
+ end
231
+
232
+ it "should return nil when given an unused ThreadGroup" do
233
+ expect(VirtFS.context_manager.remove_manager_for(ThreadGroup.new)).to be nil
234
+ end
235
+
236
+ it "should return nil when given our ThreadGroup" do
237
+ @thread_groups.each do |tg|
238
+ cm = VirtFS.context_manager.manager_for(tg)
239
+ expect(cm).to be_kind_of(VirtFS::ContextManager)
240
+ expect(VirtFS.context_manager.remove_manager_for(tg)).to eq(cm)
241
+ expect(VirtFS.context_manager.manager_for(tg)).to be nil
242
+ end
243
+ end
244
+ end
245
+ end
246
+ end
@@ -0,0 +1,255 @@
1
+ require 'spec_helper'
2
+
3
+ describe VirtFS, " - context manager instance operations (#{$fs_interface} interface)" do
4
+ before(:all) do
5
+ @root = File::SEPARATOR
6
+ end
7
+
8
+ before(:each) do
9
+ reset_context
10
+ @my_context_manager = VirtFS.context_manager.current
11
+ end
12
+
13
+ describe "#[]" do
14
+ it "should return nil given an non-existent key" do
15
+ expect(@my_context_manager[:not_a_key]).to be nil
16
+ end
17
+
18
+ it "should have a default context" do
19
+ expect(@my_context_manager[:default]).to be_kind_of(VirtFS::Context)
20
+ end
21
+ end
22
+
23
+ describe "#[]=" do
24
+ it "should raise an ArgumentError when not passed a VirtFS::Context object" do
25
+ expect do
26
+ @my_context_manager[:new_key] = "not a context object"
27
+ end.to raise_exception(ArgumentError, "Context must be a VirtFS::Context object")
28
+ end
29
+
30
+ it "should raise an ArgumentError when attempting to change the default context" do
31
+ expect do
32
+ @my_context_manager[:default] = VirtFS::Context.new
33
+ end.to raise_exception(ArgumentError, "Cannot change the default context")
34
+ end
35
+
36
+ it "should return the assigned context on success" do
37
+ new_context = VirtFS::Context.new
38
+ expect(@my_context_manager[:new_key] = new_context).to eq(new_context)
39
+ end
40
+
41
+ it "should raise an RuntimeError when attempting to change existing value" do
42
+ new_context = VirtFS::Context.new
43
+ expect(@my_context_manager[:new_key] = new_context).to eq(new_context)
44
+ expect do
45
+ @my_context_manager[:new_key] = VirtFS::Context.new
46
+ end.to raise_exception(RuntimeError, "Context for given key already exists")
47
+ end
48
+
49
+ it "should raise an RuntimeError when attempting assign context to more than one key" do
50
+ new_context = VirtFS::Context.new
51
+ expect(@my_context_manager[:new_key1] = new_context).to eq(new_context)
52
+ expect do
53
+ @my_context_manager[:new_key2] = new_context
54
+ end.to raise_exception(RuntimeError, /Context already assigned to key:/)
55
+ end
56
+
57
+ it "should delete a context by assigning nil" do
58
+ new_context = VirtFS::Context.new
59
+ expect(@my_context_manager[:new_key] = new_context).to eq(new_context)
60
+ expect(@my_context_manager[:new_key] = nil).to be nil
61
+ expect(@my_context_manager[:new_key]).to be nil
62
+ end
63
+
64
+ it "should permit re-assignment of deleted entry" do
65
+ new_context = VirtFS::Context.new
66
+ expect(@my_context_manager[:new_key] = new_context).to eq(new_context)
67
+ expect do
68
+ @my_context_manager[:new_key] = VirtFS::Context.new
69
+ end.to raise_exception(RuntimeError, "Context for given key already exists")
70
+ expect(@my_context_manager[:new_key] = nil).to be nil
71
+ expect(@my_context_manager[:new_key] = new_context).to eq(new_context)
72
+ end
73
+
74
+ it "should permit assignment to new key after deletion from old key" do
75
+ new_context = VirtFS::Context.new
76
+ expect(@my_context_manager[:new_key1] = new_context).to eq(new_context)
77
+ expect do
78
+ @my_context_manager[:new_key2] = new_context
79
+ end.to raise_exception(RuntimeError, /Context already assigned to key:/)
80
+ expect(@my_context_manager[:new_key1] = nil).to be nil
81
+ expect(@my_context_manager[:new_key2] = new_context).to eq(new_context)
82
+ end
83
+ end
84
+
85
+ describe "#current_context and #current_context=" do
86
+ it "should return the default context by default" do
87
+ expect(@my_context_manager.current_context).to eq(@my_context_manager[:default])
88
+ end
89
+
90
+ it "should raise RuntimeError when key doesn't exist" do
91
+ expect do
92
+ @my_context_manager.current_context = :new_key
93
+ end.to raise_exception(RuntimeError, "Context for given key doesn't exist")
94
+ end
95
+
96
+ it "should set the current_context to a new value" do
97
+ new_context = VirtFS::Context.new
98
+ expect(@my_context_manager[:new_key] = new_context).to eq(new_context)
99
+ expect(@my_context_manager.current_context).to eq(@my_context_manager[:default])
100
+ @my_context_manager.current_context = :new_key
101
+ expect(@my_context_manager.current_context).to eq(@my_context_manager[:new_key])
102
+ end
103
+ end
104
+
105
+ describe "#activated?" do
106
+ after(:each) do
107
+ @my_context_manager.deactivate! if @my_context_manager.activated?
108
+ end
109
+
110
+ it "should return false by default" do
111
+ expect(@my_context_manager.activated?).to be false
112
+ end
113
+
114
+ it "should return true when activated" do
115
+ @my_context_manager.activate!(:default)
116
+ expect(@my_context_manager.activated?).to be true
117
+ end
118
+ end
119
+
120
+ describe "#activate!" do
121
+ after(:each) do
122
+ @my_context_manager.deactivate! if @my_context_manager.activated?
123
+ end
124
+
125
+ it "should raise RuntimeError when key doesn't exist" do
126
+ expect do
127
+ @my_context_manager.activate!(:new_key)
128
+ end.to raise_exception(RuntimeError, "Context for given key doesn't exist")
129
+ end
130
+
131
+ it "should raise RuntimeError when already activated" do
132
+ @my_context_manager.activate!(:default)
133
+ expect do
134
+ @my_context_manager.activate!(:default)
135
+ end.to raise_exception(RuntimeError, "Context already activated")
136
+ end
137
+
138
+ it "should cause activated? to return true" do
139
+ expect(@my_context_manager.activated?).to be false
140
+ @my_context_manager.activate!(:default)
141
+ expect(@my_context_manager.activated?).to be true
142
+ end
143
+
144
+ it "should return the pre-activation context" do
145
+ new_context = VirtFS::Context.new
146
+ @my_context_manager[:new_key] = new_context
147
+ prev_context = @my_context_manager.current_context
148
+ expect(new_context).not_to eq(prev_context)
149
+ expect(@my_context_manager.activate!(:new_key)).to eq(prev_context)
150
+ end
151
+
152
+ it "should change the current context" do
153
+ new_context = VirtFS::Context.new
154
+ @my_context_manager[:new_key] = new_context
155
+ expect(@my_context_manager[:default]).not_to eq(new_context)
156
+ expect(@my_context_manager.current_context).to eq(@my_context_manager[:default])
157
+ @my_context_manager.activate!(:new_key)
158
+ expect(@my_context_manager.current_context).to eq(new_context)
159
+ end
160
+ end
161
+
162
+ describe "#deactivate!" do
163
+ it "should raise RuntimeError when not activated" do
164
+ expect do
165
+ @my_context_manager.deactivate!
166
+ end.to raise_exception(RuntimeError, "Context not activated")
167
+ end
168
+
169
+ it "should cause activated? to return false" do
170
+ expect(@my_context_manager.activated?).to be false
171
+ @my_context_manager.activate!(:default)
172
+ expect(@my_context_manager.activated?).to be true
173
+ @my_context_manager.deactivate!
174
+ expect(@my_context_manager.activated?).to be false
175
+ end
176
+
177
+ it "should return the pre-deactivated context" do
178
+ new_context = VirtFS::Context.new
179
+ @my_context_manager[:new_key] = new_context
180
+ @my_context_manager.activate!(:new_key)
181
+ expect(@my_context_manager.deactivate!).to eq(new_context)
182
+ end
183
+
184
+ it "should restore original context" do
185
+ context0 = @my_context_manager.current_context
186
+ new_context = VirtFS::Context.new
187
+ @my_context_manager[:new_key] = new_context
188
+ @my_context_manager.activate!(:new_key)
189
+ expect(@my_context_manager.current_context).not_to eq(context0)
190
+ @my_context_manager.deactivate!
191
+ expect(@my_context_manager.current_context).to eq(context0)
192
+ end
193
+ end
194
+
195
+ describe "#with" do
196
+ it "should raise RuntimeError when key doesn't exist" do
197
+ expect do
198
+ @my_context_manager.with(:new_key) {}
199
+ end.to raise_exception(RuntimeError, "Context for given key doesn't exist")
200
+ end
201
+
202
+ it "should raise RuntimeError when already activated" do
203
+ @my_context_manager.activate!(:default)
204
+ expect do
205
+ @my_context_manager.with(:default) {}
206
+ end.to raise_exception(RuntimeError, "Context already activated")
207
+ end
208
+
209
+ it "should cause activated? to return true within the block" do
210
+ expect(@my_context_manager.activated?).to be false
211
+ @my_context_manager.with(:default) do
212
+ expect(@my_context_manager.activated?).to be true
213
+ end
214
+ expect(@my_context_manager.activated?).to be false
215
+ end
216
+
217
+ it "should save and restore original context" do
218
+ context0 = @my_context_manager.current_context
219
+ new_context = VirtFS::Context.new
220
+ @my_context_manager[:new_key] = new_context
221
+ @my_context_manager.with(:new_key) do
222
+ expect(@my_context_manager.current_context).not_to eq(context0)
223
+ expect(@my_context_manager.current_context).to eq(new_context)
224
+ end
225
+ expect(@my_context_manager.current_context).to eq(context0)
226
+ end
227
+ end
228
+
229
+ describe "#without" do
230
+ it "should not change the current context when not activated" do
231
+ context0 = @my_context_manager.current_context
232
+ @my_context_manager.without do
233
+ expect(@my_context_manager.current_context).to eq(context0)
234
+ end
235
+ expect(@my_context_manager.current_context).to eq(context0)
236
+ end
237
+
238
+ it "should deactivate the context for the duration of the block" do
239
+ context0 = @my_context_manager.current_context
240
+ new_context = VirtFS::Context.new
241
+ @my_context_manager[:new_key] = new_context
242
+ @my_context_manager.with(:new_key) do
243
+ expect(@my_context_manager.current_context).not_to eq(context0)
244
+ expect(@my_context_manager.current_context).to eq(new_context)
245
+
246
+ @my_context_manager.without do
247
+ expect(@my_context_manager.current_context).to eq(context0)
248
+ end
249
+
250
+ expect(@my_context_manager.current_context).to eq(new_context)
251
+ end
252
+ expect(@my_context_manager.current_context).to eq(context0)
253
+ end
254
+ end
255
+ end