io_shuten 0.0.1.dev5 → 0.0.3.dev1
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.
- data/.travis.yml +7 -0
- data/Gemfile +3 -4
- data/Gemfile.lock +2 -8
- data/README.md +17 -3
- data/Rakefile +25 -1
- data/benchmark/compare_mem_w_buf.rb +134 -0
- data/doc/IO_3A_3ABuffer.html +198 -0
- data/doc/IO_shuten/Base.html +349 -1943
- data/doc/IO_shuten/Buffer.html +1842 -0
- data/doc/IO_shuten/Errors/FileAccessError.html +5 -4
- data/doc/IO_shuten/Errors/FileNotFoundError.html +5 -4
- data/doc/IO_shuten/Errors/NodeExistsError.html +5 -4
- data/doc/IO_shuten/Errors/NodeNameError.html +5 -4
- data/doc/IO_shuten/Errors/NodeNotFoundError.html +5 -4
- data/doc/IO_shuten/Errors/NotYetImplemented.html +5 -4
- data/doc/IO_shuten/Errors.html +5 -4
- data/doc/IO_shuten/Memory.html +1798 -0
- data/doc/IO_shuten/Mongo.html +9 -13
- data/doc/IO_shuten/Redis.html +803 -8
- data/doc/IO_shuten/Stores/Mongo/Collection.html +5 -4
- data/doc/IO_shuten/Stores/Mongo/GridFS.html +5 -4
- data/doc/IO_shuten/Stores/Mongo.html +5 -4
- data/doc/IO_shuten/Stores/Redis/KeyValue.html +5 -4
- data/doc/IO_shuten/Stores/Redis/PubSub.html +5 -4
- data/doc/IO_shuten/Stores/Redis.html +5 -4
- data/doc/IO_shuten/Stores.html +5 -4
- data/doc/IO_shuten.html +7 -6
- data/doc/_index.html +20 -6
- data/doc/class_list.html +1 -1
- data/doc/file.README.html +21 -6
- data/doc/index.html +21 -6
- data/doc/method_list.html +119 -15
- data/doc/top-level-namespace.html +2 -2
- data/io_shuten.gemspec +16 -12
- data/lib/io_shuten/base.rb +1 -129
- data/lib/io_shuten/buffer.rb +156 -0
- data/lib/io_shuten/memory.rb +145 -0
- data/lib/io_shuten/redis.rb +65 -0
- data/lib/io_shuten/version.rb +1 -1
- data/lib/io_shuten.rb +2 -0
- data/spec/examples/logger_spec.rb +18 -2
- data/spec/lib/buffer_spec.rb +387 -0
- data/spec/lib/{base_spec.rb → memory_spec.rb} +92 -82
- data/spec/lib/mongo_spec.rb +1 -1
- data/spec/lib/redis_spec.rb +1 -1
- data/spec/spec_helper.rb +16 -12
- metadata +233 -163
@@ -3,8 +3,9 @@ require File.expand_path("../../spec_helper.rb", __FILE__)
|
|
3
3
|
require "logger"
|
4
4
|
|
5
5
|
describe "Logger" do
|
6
|
-
|
7
|
-
|
6
|
+
|
7
|
+
it "accepts an IO_shuten::Memory as logdev" do
|
8
|
+
logdev = IO_shuten::Memory.new(:mlogdev)
|
8
9
|
logger = Logger.new(logdev)
|
9
10
|
logger.info "Foo log."
|
10
11
|
logger.info "Test message."
|
@@ -12,4 +13,19 @@ describe "Logger" do
|
|
12
13
|
|
13
14
|
logdev.string.should =~ /Test message/
|
14
15
|
end
|
16
|
+
|
17
|
+
it "accepts an IO_shuten::Buffer as logdev" do
|
18
|
+
logdev = IO_shuten::Buffer.new(:blogdev)
|
19
|
+
logger = Logger.new(logdev)
|
20
|
+
logger.info "Foo log."
|
21
|
+
logger.info "Test message."
|
22
|
+
logger.info "Bar log."
|
23
|
+
|
24
|
+
logdev.read.should =~ /Test message/
|
25
|
+
end
|
26
|
+
|
27
|
+
it "accepts an IO_shuten::Redis as logdev"
|
28
|
+
|
29
|
+
it "accepts an IO_shuten::Mongo as logdev"
|
30
|
+
|
15
31
|
end
|
@@ -0,0 +1,387 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
require File.expand_path("../../spec_helper.rb", __FILE__)
|
3
|
+
|
4
|
+
include IO_shuten
|
5
|
+
describe Buffer do
|
6
|
+
|
7
|
+
describe "Class Methods" do
|
8
|
+
|
9
|
+
describe :new do
|
10
|
+
|
11
|
+
context "without node_name" do
|
12
|
+
it "raises Errors::NodeNameError" do
|
13
|
+
expect { Buffer.new }.to raise_error(Errors::NodeNameError)
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
context "with node_name" do
|
18
|
+
it "creates a new node with name as String" do
|
19
|
+
node_name = "foo bar"
|
20
|
+
iob = Buffer.new(node_name)
|
21
|
+
iob.should be_an(IO_shuten::Buffer)
|
22
|
+
iob.node_name.should == node_name
|
23
|
+
end
|
24
|
+
|
25
|
+
it "creates a new node with name as Symbol" do
|
26
|
+
node_name = :foobar
|
27
|
+
iob = Buffer.new(node_name)
|
28
|
+
iob.should be_an(IO_shuten::Buffer)
|
29
|
+
iob.node_name.should == node_name
|
30
|
+
end
|
31
|
+
|
32
|
+
it "raises NodeNameError if wrong type" do
|
33
|
+
node_name = 1.23
|
34
|
+
expect { Buffer.new(node_name) }.to raise_error(Errors::NodeNameError)
|
35
|
+
end
|
36
|
+
|
37
|
+
it "raises NodeExistsError if node name is already taken" do
|
38
|
+
node_name = :already_taken
|
39
|
+
expect { Buffer.new(node_name) }.to_not raise_error
|
40
|
+
expect { Buffer.new(node_name) }.to raise_error(Errors::NodeExistsError)
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
end
|
45
|
+
|
46
|
+
describe "class based Buffer storage" do
|
47
|
+
describe :purge_instances! do
|
48
|
+
it "purges all instances" do
|
49
|
+
Buffer.purge_instances!
|
50
|
+
Buffer.instances.should have(0).items
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
describe :instances do
|
55
|
+
it "retrieves all @@instances" do
|
56
|
+
Buffer.purge_instances!
|
57
|
+
nodes = %w[first second last]
|
58
|
+
nodes.each do |node_name|
|
59
|
+
Buffer.new(node_name)
|
60
|
+
end
|
61
|
+
|
62
|
+
Buffer.instances.should have(3).items
|
63
|
+
end
|
64
|
+
end
|
65
|
+
|
66
|
+
describe :delete_instance do
|
67
|
+
before do
|
68
|
+
Buffer.purge_instances!
|
69
|
+
@node_names = %w[first second last]
|
70
|
+
@nodes = @node_names.inject([]) do |store, node_name|
|
71
|
+
store << Buffer.new(node_name)
|
72
|
+
store
|
73
|
+
end
|
74
|
+
end
|
75
|
+
|
76
|
+
it "removes an node by name from store" do
|
77
|
+
Buffer.delete_instance(@node_names.first)
|
78
|
+
Buffer.instances.should_not include(@nodes.first)
|
79
|
+
end
|
80
|
+
|
81
|
+
it "removes an node by instance from store" do
|
82
|
+
Buffer.delete_instance(@nodes.first)
|
83
|
+
Buffer.instances.should_not include(@nodes.first)
|
84
|
+
end
|
85
|
+
|
86
|
+
it "removes an node by symbolized name from store" do
|
87
|
+
Buffer.purge_instances!
|
88
|
+
@node_names = %w[first second last].map(&:to_sym)
|
89
|
+
@nodes = @node_names.inject([]) do |store, node_name|
|
90
|
+
store << Buffer.new(node_name)
|
91
|
+
store
|
92
|
+
end
|
93
|
+
Buffer.delete_instance(@node_names.first)
|
94
|
+
Buffer.instances.should_not include(@nodes.first)
|
95
|
+
end
|
96
|
+
|
97
|
+
end
|
98
|
+
|
99
|
+
describe "batch tasks" do
|
100
|
+
|
101
|
+
before do
|
102
|
+
Buffer.purge_instances!
|
103
|
+
|
104
|
+
@tmp_path = File.expand_path("../../../tmp", __FILE__)
|
105
|
+
|
106
|
+
Dir.mkdir(@tmp_path) unless File.exists?(@tmp_path)
|
107
|
+
|
108
|
+
@example_content = "This is a dummy file!"
|
109
|
+
|
110
|
+
@file_names = %w[file1 file2 file3]
|
111
|
+
|
112
|
+
@file_names.each do |file_name|
|
113
|
+
File.open("#{@tmp_path}/#{file_name}",'w') do |fh|
|
114
|
+
fh.puts file_name
|
115
|
+
fh.puts @example_content
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
after do
|
121
|
+
@file_names.each do |file_name|
|
122
|
+
File.unlink("#{@tmp_path}/#{file_name}") if File.exists?("#{@tmp_path}/#{file_name}")
|
123
|
+
end
|
124
|
+
Buffer.purge_instances!
|
125
|
+
end
|
126
|
+
|
127
|
+
describe :save_instances do
|
128
|
+
before do
|
129
|
+
@file_names2 = %w[file4 file5 file6]
|
130
|
+
end
|
131
|
+
|
132
|
+
after do
|
133
|
+
@file_names2.each do |file_name|
|
134
|
+
File.unlink("#{@tmp_path}/#{file_name}") if File.exists?("#{@tmp_path}/#{file_name}")
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
it "writes all instances to disk" do
|
139
|
+
@file_names2.each do |file_name|
|
140
|
+
node = Buffer.new("#{@tmp_path}/#{file_name}")
|
141
|
+
node.<< "content of file: #{file_name}"
|
142
|
+
end
|
143
|
+
|
144
|
+
Buffer.save_instances.should be_true
|
145
|
+
end
|
146
|
+
end
|
147
|
+
|
148
|
+
describe :load_instances do
|
149
|
+
it "loads an array of files" do
|
150
|
+
absolute_files = @file_names.inject([]) do |store, file_name|
|
151
|
+
store << "#{@tmp_path}/#{file_name}"
|
152
|
+
end
|
153
|
+
Buffer.load_instances absolute_files
|
154
|
+
Buffer.pool.should have(3).items
|
155
|
+
end
|
156
|
+
|
157
|
+
it "loads an array of files provided by Dir.glob" do
|
158
|
+
Buffer.load_instances Dir.glob(@tmp_path+"/**/*")
|
159
|
+
Buffer.pool.should have(3).items
|
160
|
+
end
|
161
|
+
|
162
|
+
it "loads files from a directory name (String)" do
|
163
|
+
Buffer.load_instances @tmp_path
|
164
|
+
Buffer.pool.should have(3).items
|
165
|
+
end
|
166
|
+
end
|
167
|
+
|
168
|
+
end
|
169
|
+
|
170
|
+
|
171
|
+
end # class based Buffer storage
|
172
|
+
|
173
|
+
describe :open do
|
174
|
+
|
175
|
+
before do
|
176
|
+
Buffer.purge_instances!
|
177
|
+
end
|
178
|
+
|
179
|
+
context "without any args" do
|
180
|
+
it "raises ArgumentError" do
|
181
|
+
expect { Buffer.open }.to raise_error(::ArgumentError)
|
182
|
+
end
|
183
|
+
end
|
184
|
+
|
185
|
+
context "with name only" do
|
186
|
+
|
187
|
+
context "and node does not exist" do
|
188
|
+
it "raises NodeNotFound error" do
|
189
|
+
expect { Buffer.open("foo bar") }.to raise_error(Errors::NodeNotFoundError)
|
190
|
+
end
|
191
|
+
end
|
192
|
+
|
193
|
+
context "and node exists" do
|
194
|
+
it "returns the requested node" do
|
195
|
+
node_name = "foo bar"
|
196
|
+
stored_obj = Buffer.new(node_name)
|
197
|
+
|
198
|
+
iob = Buffer.open(node_name)
|
199
|
+
iob.should === stored_obj
|
200
|
+
end
|
201
|
+
|
202
|
+
end
|
203
|
+
end
|
204
|
+
|
205
|
+
context "with name and block" do
|
206
|
+
|
207
|
+
it "opens node and yields the block" do
|
208
|
+
str = "string set in block"
|
209
|
+
origin = Buffer.new(:blocktest)
|
210
|
+
|
211
|
+
open_obj = Buffer.open :blocktest do |handle|
|
212
|
+
handle.write str
|
213
|
+
end
|
214
|
+
|
215
|
+
open_obj.should === origin
|
216
|
+
origin.read.should === str
|
217
|
+
end
|
218
|
+
|
219
|
+
it "can reopen an node for manipulation" do
|
220
|
+
str = "string set in block"
|
221
|
+
other_str = "new string"
|
222
|
+
origin = Buffer.new(:blocktest)
|
223
|
+
|
224
|
+
Buffer.open :blocktest do |handle|
|
225
|
+
handle.write str
|
226
|
+
end
|
227
|
+
|
228
|
+
expect do
|
229
|
+
Buffer.open :blocktest do |handle|
|
230
|
+
handle.write other_str
|
231
|
+
end
|
232
|
+
end.to_not raise_error
|
233
|
+
Buffer.open(:blocktest).read.should match(other_str)
|
234
|
+
end
|
235
|
+
|
236
|
+
end
|
237
|
+
|
238
|
+
end # open
|
239
|
+
|
240
|
+
end # Class Methods
|
241
|
+
|
242
|
+
describe "Instance Methods" do
|
243
|
+
|
244
|
+
before do
|
245
|
+
Buffer.purge_instances!
|
246
|
+
end
|
247
|
+
|
248
|
+
describe "IO::Buffer method wrapper (for: #{RUBY_VERSION})" do
|
249
|
+
method_list = %w[
|
250
|
+
<<
|
251
|
+
append
|
252
|
+
clear
|
253
|
+
empty?
|
254
|
+
gets
|
255
|
+
prepend print printf putc puts
|
256
|
+
read readline readlines read_from
|
257
|
+
size
|
258
|
+
write write_to
|
259
|
+
]
|
260
|
+
|
261
|
+
method_list.each do |method_name|
|
262
|
+
it "- responds to ##{method_name}" do
|
263
|
+
Buffer.new(:string_io_test).should respond_to(method_name)
|
264
|
+
end
|
265
|
+
end
|
266
|
+
end
|
267
|
+
|
268
|
+
describe "method stub with #not_yet_implemented! call" do
|
269
|
+
it "raises NotYetImplemented" do
|
270
|
+
iob = Buffer.new(:not_implemented)
|
271
|
+
iob.instance_eval do
|
272
|
+
def not_implemented_method_a
|
273
|
+
not_yet_implemented!
|
274
|
+
end
|
275
|
+
def not_implemented_method_b
|
276
|
+
not_yet_implemented! __method__, "#{__FILE__}:#{__LINE__}"
|
277
|
+
end
|
278
|
+
end
|
279
|
+
expect { iob.not_implemented_method_a }.to raise_error(Errors::NotYetImplemented)
|
280
|
+
expect { iob.not_implemented_method_b }.to raise_error(Errors::NotYetImplemented)
|
281
|
+
expect { iob.not_implemented_method_c }.to raise_error(Errors::NotYetImplemented)
|
282
|
+
end
|
283
|
+
end
|
284
|
+
|
285
|
+
describe "loading and writing" do
|
286
|
+
|
287
|
+
before do
|
288
|
+
@tmp_path = File.expand_path("../../../tmp", __FILE__)
|
289
|
+
@tmp_true_file = "#{@tmp_path}/base.exist_true.txt"
|
290
|
+
@tmp_save_file = "#{@tmp_path}/base.save_true.txt"
|
291
|
+
@tmp_false_file = "#{@tmp_path}/base.exist_false.txt"
|
292
|
+
@denied_path = "/invalid_file.txt"
|
293
|
+
|
294
|
+
Dir.mkdir(@tmp_path) unless File.exists?(@tmp_path)
|
295
|
+
f = File.new(@tmp_true_file,'w')
|
296
|
+
f.puts "true content"
|
297
|
+
f.close
|
298
|
+
end
|
299
|
+
|
300
|
+
after do
|
301
|
+
File.unlink(@tmp_true_file)
|
302
|
+
File.unlink(@tmp_save_file) if File.exists?(@tmp_save_file)
|
303
|
+
Buffer.purge_instances!
|
304
|
+
end
|
305
|
+
|
306
|
+
describe :file_exists? do
|
307
|
+
|
308
|
+
it "returns true if path is a file" do
|
309
|
+
iob = Buffer.new(@tmp_true_file)
|
310
|
+
iob.file_exists?.should be_true
|
311
|
+
end
|
312
|
+
|
313
|
+
it "returns true if custom path is a file" do
|
314
|
+
iob = Buffer.new(:different_name)
|
315
|
+
iob.file_exists?(@tmp_true_file).should be_true
|
316
|
+
end
|
317
|
+
|
318
|
+
it "returns false if path is not a file" do
|
319
|
+
iob = Buffer.new(@tmp_false_file)
|
320
|
+
iob.file_exists?.should be_false
|
321
|
+
end
|
322
|
+
|
323
|
+
end
|
324
|
+
|
325
|
+
describe :load_from_file do
|
326
|
+
|
327
|
+
context "file exists" do
|
328
|
+
|
329
|
+
it "reads file and stores content into container" do
|
330
|
+
iob = Buffer.new(@tmp_true_file)
|
331
|
+
iob.load_from_file.should be_true
|
332
|
+
iob.read.should =~ /true content/
|
333
|
+
end
|
334
|
+
|
335
|
+
it "reads file with custom name" do
|
336
|
+
iob = Buffer.new(:different_name)
|
337
|
+
iob.load_from_file(@tmp_true_file).should be_true
|
338
|
+
iob.read.should =~ /content/
|
339
|
+
end
|
340
|
+
|
341
|
+
end
|
342
|
+
|
343
|
+
context "file does not exist" do
|
344
|
+
it "raises FileNotFoundError" do
|
345
|
+
iob = Buffer.new(@tmp_false_file)
|
346
|
+
expect { iob.load_from_file }.to raise_error(Errors::FileNotFoundError)
|
347
|
+
end
|
348
|
+
end
|
349
|
+
|
350
|
+
end
|
351
|
+
|
352
|
+
describe :save_to_file do
|
353
|
+
|
354
|
+
context "file path accessible" do
|
355
|
+
context "with container name as default" do
|
356
|
+
it "writes container into the file" do
|
357
|
+
iob = Buffer.new(@tmp_save_file)
|
358
|
+
iob.puts "Test string"
|
359
|
+
iob.save_to_file.should be_true
|
360
|
+
end
|
361
|
+
end
|
362
|
+
|
363
|
+
context "with custom name" do
|
364
|
+
it "writes container into the file" do
|
365
|
+
iob = Buffer.new(:different_name)
|
366
|
+
iob.puts "Test string"
|
367
|
+
iob.save_to_file(@tmp_save_file).should be_true
|
368
|
+
end
|
369
|
+
end
|
370
|
+
|
371
|
+
end
|
372
|
+
|
373
|
+
context "path not accessible" do
|
374
|
+
it "raises FileAccessError with corresponding reason" do
|
375
|
+
iob = Buffer.new(@denied_path)
|
376
|
+
iob.puts "Test string"
|
377
|
+
expect { iob.save_to_file }.to raise_error(Errors::FileAccessError, /Reason/)
|
378
|
+
end
|
379
|
+
end
|
380
|
+
|
381
|
+
end
|
382
|
+
|
383
|
+
end # loading and writing
|
384
|
+
|
385
|
+
end
|
386
|
+
|
387
|
+
end
|