io_shuten 0.0.1.dev4 → 0.0.1.dev5

Sign up to get free protection for your applications and to get access to all the features.
Files changed (73) hide show
  1. data/.travis.yml +5 -0
  2. data/.yardopts +0 -1
  3. data/Gemfile +1 -1
  4. data/Gemfile.lock +0 -3
  5. data/Rakefile +0 -6
  6. data/doc/IO_shuten.html +126 -0
  7. data/doc/IO_shuten/Base.html +2677 -0
  8. data/doc/IO_shuten/Base/FileAccessError.html +129 -0
  9. data/doc/IO_shuten/Base/FileNotFoundError.html +129 -0
  10. data/doc/IO_shuten/Base/NodeNameError.html +129 -0
  11. data/doc/IO_shuten/Base/NodeNotFoundError.html +129 -0
  12. data/doc/IO_shuten/Base/NotYetImplemented.html +129 -0
  13. data/doc/IO_shuten/Errors.html +119 -0
  14. data/doc/IO_shuten/Errors/FileAccessError.html +129 -0
  15. data/doc/IO_shuten/Errors/FileNotFoundError.html +129 -0
  16. data/doc/IO_shuten/Errors/NodeExistsError.html +129 -0
  17. data/doc/IO_shuten/Errors/NodeNameError.html +129 -0
  18. data/doc/IO_shuten/Errors/NodeNameExistsError.html +129 -0
  19. data/doc/IO_shuten/Errors/NodeNotFoundError.html +129 -0
  20. data/doc/IO_shuten/Errors/NotYetImplemented.html +129 -0
  21. data/doc/IO_shuten/Mongo.html +172 -0
  22. data/doc/IO_shuten/Redis.html +172 -0
  23. data/doc/IO_shuten/Stores.html +121 -0
  24. data/doc/IO_shuten/Stores/Mongo.html +121 -0
  25. data/doc/IO_shuten/Stores/Mongo/Collection.html +109 -0
  26. data/doc/IO_shuten/Stores/Mongo/GridFS.html +109 -0
  27. data/doc/IO_shuten/Stores/Redis.html +121 -0
  28. data/doc/IO_shuten/Stores/Redis/KeyValue.html +109 -0
  29. data/doc/IO_shuten/Stores/Redis/PubSub.html +109 -0
  30. data/doc/_index.html +318 -0
  31. data/doc/class_list.html +47 -0
  32. data/doc/css/blame.css +11 -0
  33. data/doc/css/common.css +1 -0
  34. data/doc/css/full_list.css +55 -0
  35. data/doc/css/style.css +322 -0
  36. data/doc/file.README.html +136 -0
  37. data/doc/file_list.html +49 -0
  38. data/doc/frames.html +13 -0
  39. data/doc/index.html +136 -0
  40. data/doc/js/app.js +205 -0
  41. data/doc/js/full_list.js +167 -0
  42. data/doc/js/jquery.js +16 -0
  43. data/doc/method_list.html +150 -0
  44. data/doc/top-level-namespace.html +105 -0
  45. data/io_shuten.gemspec +57 -10
  46. data/lib/io_shuten.rb +3 -1
  47. data/lib/io_shuten/base.rb +105 -67
  48. data/lib/io_shuten/errors.rb +42 -0
  49. data/lib/io_shuten/redis.rb +2 -0
  50. data/lib/io_shuten/stores.rb +11 -0
  51. data/lib/io_shuten/stores/mongo.rb +11 -0
  52. data/lib/io_shuten/stores/mongo/collection.rb +7 -0
  53. data/lib/io_shuten/stores/mongo/gridfs.rb +7 -0
  54. data/lib/io_shuten/stores/redis.rb +11 -0
  55. data/lib/io_shuten/stores/redis/key_value.rb +7 -0
  56. data/lib/io_shuten/stores/redis/pub_sub.rb +7 -0
  57. data/lib/io_shuten/version.rb +1 -1
  58. data/spec/lib/base_spec.rb +163 -73
  59. data/spec/lib/mongo_spec.rb +1 -1
  60. data/spec/lib/redis_spec.rb +1 -1
  61. data/spec/lib/stores/mongo/collection_spec.rb +7 -0
  62. data/spec/lib/stores/mongo/gridfs_spec.rb +7 -0
  63. data/spec/lib/stores/mongo_spec.rb +7 -0
  64. data/spec/lib/stores/redis/key_value_spec.rb +7 -0
  65. data/spec/lib/stores/redis/pub_sub_spec.rb +7 -0
  66. data/spec/lib/stores/redis_spec.rb +7 -0
  67. data/spec/lib/stores_spec.rb +7 -0
  68. data/spec/spec_helper.rb +9 -0
  69. metadata +90 -51
  70. data/.rdoc_options +0 -20
  71. data/.yardoc/checksums +0 -5
  72. data/.yardoc/objects/root.dat +0 -0
  73. data/.yardoc/proxy_types +0 -0
@@ -0,0 +1,42 @@
1
+ # encoding: utf-8
2
+
3
+ module IO_shuten
4
+
5
+ # Collection of Errors/Exceptions
6
+ module Errors
7
+
8
+ # Exception if a node object was not found
9
+ class NodeNotFoundError < ::StandardError
10
+ end
11
+
12
+ # Exception if the node object name was of wrong type
13
+ class NodeNameError < ::StandardError
14
+ end
15
+
16
+ # Exception if the node object name was found in pool
17
+ class NodeExistsError < ::StandardError
18
+ end
19
+
20
+ # Exception if file was not found
21
+ class FileNotFoundError < ::StandardError
22
+ end
23
+
24
+ # Exception if something went wrong on file handling
25
+ class FileAccessError < ::StandardError
26
+ end
27
+
28
+ # Exception for not yet implemented methods (stubs)
29
+ class NotYetImplemented < ::StandardError
30
+ # @private
31
+ def initialize callee = nil, pos = nil
32
+ msg = if callee
33
+ "Method :#{callee} is not (yet) supported. #{pos ? ''+pos+'' : ''}"
34
+ else
35
+ "The method is not (yet) supported."
36
+ end
37
+ super msg
38
+ end
39
+ end
40
+
41
+ end
42
+ end
@@ -2,6 +2,8 @@
2
2
 
3
3
  module IO_shuten
4
4
  # Implementation of the Redis storage
5
+ #
6
+ # @todo Needs two backends (default database interface and pub/sub interface)!
5
7
  class Redis < IO_shuten::Base
6
8
 
7
9
  end
@@ -0,0 +1,11 @@
1
+ # encoding: utf-8
2
+
3
+ module IO_shuten
4
+ # Namespace for the storage implementations
5
+ module Stores
6
+ end
7
+ end
8
+
9
+ require "io_shuten/stores/mongo"
10
+ require "io_shuten/stores/redis"
11
+
@@ -0,0 +1,11 @@
1
+ # encoding: utf-8
2
+
3
+ module IO_shuten::Stores
4
+ # Namespace for mongodb backends
5
+ module Mongo
6
+ end
7
+ end
8
+
9
+ require "io_shuten/stores/mongo/collection"
10
+ require "io_shuten/stores/mongo/gridfs"
11
+
@@ -0,0 +1,7 @@
1
+ # encoding: utf-8
2
+
3
+ module IO_shuten::Stores::Mongo
4
+ # MongoDB Backend for Collection based storage
5
+ module Collection
6
+ end
7
+ end
@@ -0,0 +1,7 @@
1
+ # encoding: utf-8
2
+
3
+ module IO_shuten::Stores::Mongo
4
+ # MongoDB Backend for GridFS based storage
5
+ module GridFS
6
+ end
7
+ end
@@ -0,0 +1,11 @@
1
+ # encoding: utf-8
2
+
3
+ module IO_shuten::Stores
4
+ # Namespace for redis backends
5
+ module Redis
6
+ end
7
+ end
8
+
9
+ require "io_shuten/stores/redis/key_value"
10
+ require "io_shuten/stores/redis/pub_sub"
11
+
@@ -0,0 +1,7 @@
1
+ # encoding: utf-8
2
+
3
+ module IO_shuten::Stores::Redis
4
+ # Redis Backend for key-value based storage
5
+ module KeyValue
6
+ end
7
+ end
@@ -0,0 +1,7 @@
1
+ # encoding: utf-8
2
+
3
+ module IO_shuten::Stores::Redis
4
+ # Redis Backend for pub-sub (event/message) based storage
5
+ module PubSub
6
+ end
7
+ end
@@ -1,5 +1,5 @@
1
1
  # encoding: utf-8
2
2
  module IO_shuten
3
3
  # @private
4
- VERSION = [0,0,1,'dev4'].join('.')
4
+ VERSION = [0,0,1,'dev5'].join('.')
5
5
  end
@@ -8,27 +8,36 @@ describe Base do
8
8
 
9
9
  describe :new do
10
10
 
11
- context "without object_name" do
12
- it "creates a new object with nil name" do
13
- ios = Base.new
14
- ios.should be_an(IO_shuten::Base)
15
- ios.object_name.should be_nil
11
+ context "without node_name" do
12
+ it "raises " do
13
+ expect { Base.new }.to raise_error(Errors::NodeNameError)
16
14
  end
17
15
  end
18
16
 
19
- context "with object_name" do
20
- it "creates a new object with name as String" do
21
- object_name = "foo bar"
22
- ios = Base.new(object_name)
17
+ context "with node_name" do
18
+ it "creates a new node with name as String" do
19
+ node_name = "foo bar"
20
+ ios = Base.new(node_name)
23
21
  ios.should be_an(IO_shuten::Base)
24
- ios.object_name.should == object_name
22
+ ios.node_name.should == node_name
25
23
  end
26
24
 
27
- it "creates a new object with name as Symbol" do
28
- object_name = :foobar
29
- ios = Base.new(object_name)
25
+ it "creates a new node with name as Symbol" do
26
+ node_name = :foobar
27
+ ios = Base.new(node_name)
30
28
  ios.should be_an(IO_shuten::Base)
31
- ios.object_name.should == object_name
29
+ ios.node_name.should == node_name
30
+ end
31
+
32
+ it "raises NodeNameError if wrong type" do
33
+ node_name = 1.23
34
+ expect { Base.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 { Base.new(node_name) }.to_not raise_error
40
+ expect { Base.new(node_name) }.to raise_error(Errors::NodeExistsError)
32
41
  end
33
42
  end
34
43
 
@@ -45,9 +54,9 @@ describe Base do
45
54
  describe :instances do
46
55
  it "retrieves all @@instances" do
47
56
  Base.purge_instances!
48
- objects = %w[first second last]
49
- objects.each do |object_name|
50
- Base.new(object_name)
57
+ nodes = %w[first second last]
58
+ nodes.each do |node_name|
59
+ Base.new(node_name)
51
60
  end
52
61
 
53
62
  Base.instances.should have(3).items
@@ -57,32 +66,32 @@ describe Base do
57
66
  describe :delete_instance do
58
67
  before do
59
68
  Base.purge_instances!
60
- @object_names = %w[first second last]
61
- @objects = @object_names.inject([]) do |store, object_name|
62
- store << Base.new(object_name)
69
+ @node_names = %w[first second last]
70
+ @nodes = @node_names.inject([]) do |store, node_name|
71
+ store << Base.new(node_name)
63
72
  store
64
73
  end
65
74
  end
66
75
 
67
- it "removes an instance by name from store" do
68
- Base.delete_instance(@object_names.first)
69
- Base.instances.should_not include(@objects.first)
76
+ it "removes an node by name from store" do
77
+ Base.delete_instance(@node_names.first)
78
+ Base.instances.should_not include(@nodes.first)
70
79
  end
71
80
 
72
- it "removes an instance by object from store" do
73
- Base.delete_instance(@objects.first)
74
- Base.instances.should_not include(@objects.first)
81
+ it "removes an node by instance from store" do
82
+ Base.delete_instance(@nodes.first)
83
+ Base.instances.should_not include(@nodes.first)
75
84
  end
76
85
 
77
- it "removes an instance by symbolized name from store" do
86
+ it "removes an node by symbolized name from store" do
78
87
  Base.purge_instances!
79
- @object_names = %w[first second last].map(&:to_sym)
80
- @objects = @object_names.inject([]) do |store, object_name|
81
- store << Base.new(object_name)
88
+ @node_names = %w[first second last].map(&:to_sym)
89
+ @nodes = @node_names.inject([]) do |store, node_name|
90
+ store << Base.new(node_name)
82
91
  store
83
92
  end
84
- Base.delete_instance(@object_names.first)
85
- Base.instances.should_not include(@objects.first)
93
+ Base.delete_instance(@node_names.first)
94
+ Base.instances.should_not include(@nodes.first)
86
95
  end
87
96
 
88
97
  end
@@ -96,13 +105,14 @@ describe Base do
96
105
 
97
106
  Dir.mkdir(@tmp_path) unless File.exists?(@tmp_path)
98
107
 
99
- example_content = "This is a dummy file!"
108
+ @example_content = "This is a dummy file!"
100
109
 
101
110
  @file_names = %w[file1 file2 file3]
102
111
 
103
112
  @file_names.each do |file_name|
104
113
  File.open("#{@tmp_path}/#{file_name}",'w') do |fh|
105
- fh.puts example_content
114
+ fh.puts file_name
115
+ fh.puts @example_content
106
116
  end
107
117
  end
108
118
  end
@@ -115,14 +125,43 @@ describe Base do
115
125
  end
116
126
 
117
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
+
118
138
  it "writes all instances to disk" do
119
- pending
139
+ @file_names2.each do |file_name|
140
+ node = Base.new("#{@tmp_path}/#{file_name}")
141
+ node.puts "content of file: #{file_name}"
142
+ end
143
+
144
+ Base.save_instances.should be_true
120
145
  end
121
146
  end
122
147
 
123
148
  describe :load_instances do
124
- it "loads instances from disk" do
125
- pending
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
+ Base.load_instances absolute_files
154
+ Base.pool.should have(3).items
155
+ end
156
+
157
+ it "loads an array of files provided by Dir.glob" do
158
+ Base.load_instances Dir.glob(@tmp_path+"/**/*")
159
+ Base.pool.should have(3).items
160
+ end
161
+
162
+ it "loads files from a directory name (String)" do
163
+ Base.load_instances @tmp_path
164
+ Base.pool.should have(3).items
126
165
  end
127
166
  end
128
167
 
@@ -139,39 +178,69 @@ describe Base do
139
178
 
140
179
  context "without any args" do
141
180
  it "raises ArgumentError" do
142
- expect { Base.open }.to raise_error(ArgumentError)
181
+ expect { Base.open }.to raise_error(::ArgumentError)
143
182
  end
144
183
  end
145
184
 
146
185
  context "with name only" do
147
186
 
148
- context "and object does not exist" do
187
+ context "and node does not exist" do
149
188
  it "raises NodeNotFound error" do
150
- Base.stub(:exists?).and_return(false)
151
- expect { Base.open("foo bar") }.to raise_error(Base::NodeNotFoundError)
189
+ expect { Base.open("foo bar") }.to raise_error(Errors::NodeNotFoundError)
152
190
  end
153
191
  end
154
192
 
155
- context "and object exists" do
156
- it "returns the requested object" do
157
- object_name = "foo bar"
158
- object_cont = "demo content of object"
159
- object_mock = double(Base, :object_name => object_name, :container => object_cont)
193
+ context "and node exists" do
194
+ it "returns the requested node" do
195
+ node_name = "foo bar"
196
+ stored_obj = Base.new(node_name)
160
197
 
161
- Base.should_receive(:exists?).with(object_name).and_return(true)
162
- Base.should_receive(:load).and_return(object_mock)
198
+ ios = Base.open(node_name)
199
+ ios.should === stored_obj
200
+ end
163
201
 
164
- ios = Base.open(object_name)
202
+ it "always reopens node for writing (and reading)" do
203
+ node_name = :always_reopenable
204
+ node = Base.new(node_name)
205
+ node.close
165
206
 
166
- ios.object_name.should == object_name
167
- ios.container.should == object_cont
207
+ node.should be_closed
208
+ Base.open(node_name).should_not be_closed
168
209
  end
169
210
  end
170
211
  end
171
212
 
172
213
  context "with name and block" do
173
- it "opens object, yields the block and closes object" do
174
- pending
214
+ it "opens node, yields the block and closes node for writing" do
215
+ str = "string set in block"
216
+ origin = Base.new(:blocktest)
217
+
218
+ open_obj = Base.open :blocktest do |handle|
219
+ handle.write str
220
+ end
221
+
222
+ open_obj.should === origin
223
+ origin.string.should === str
224
+ origin.should be_closed_write
225
+ origin.should_not be_closed_read
226
+ expect { origin.write 'foo' }.to raise_error(IOError)
227
+ end
228
+
229
+ it "can reopen an node for manipulation" do
230
+ str = "string set in block"
231
+ other_str = "new string"
232
+ origin = Base.new(:blocktest)
233
+
234
+ Base.open :blocktest do |handle|
235
+ handle.write str
236
+ end
237
+
238
+ expect do
239
+ Base.open :blocktest do |handle|
240
+ handle.puts other_str
241
+ end
242
+ end.to_not raise_error
243
+ Base.open(:blocktest).string.should match(other_str)
175
244
  end
176
245
  end
177
246
 
@@ -181,41 +250,62 @@ describe Base do
181
250
 
182
251
  describe "Instance Methods" do
183
252
 
184
- describe "StringIO method wrapper" do
185
- method_list = %w[
253
+ before do
254
+ Base.purge_instances!
255
+ end
256
+
257
+ describe "StringIO method wrapper (for: #{RUBY_VERSION})" do
258
+ m18 = %w[
186
259
  binmode bytes
187
- chars close close_read close_write closed? closed_read? closed_write? codepoints
188
- each each_byte each_char each_codepoint each_line
260
+ chars close close_read close_write closed? closed_read? closed_write?
261
+ each each_byte each_char each_line
189
262
  eof eof?
190
- external_encoding
191
263
  fcntl fileno flush fsync
192
264
  getbyte getc gets
193
- internal_encoding isatty
265
+ isatty
194
266
  length lineno lineno= lines
195
267
  pid pos pos= print printf putc puts
196
- read read_nonblock readbyte readchar readline readlines readpartial
268
+ read readbyte readchar readline readlines
197
269
  reopen rewind
198
- seek set_encoding size string string= sync sync= sysread syswrite
270
+ seek size string string= sync sync= sysread syswrite
199
271
  tell truncate tty?
200
- ungetbyte ungetc
201
- write write_nonblock
272
+ ungetc
273
+ write
202
274
  ]
275
+ m19_additionals = %w[
276
+ codepoints
277
+ each_codepoint
278
+ external_encoding
279
+ internal_encoding
280
+ read_nonblock
281
+ readpartial
282
+ set_encoding
283
+ ungetbyte
284
+ write_nonblock
285
+ ]
286
+ method_list = RUBY_VERSION =~ /^1\.8\./ ? m18 : (m18 + m19_additionals)
287
+
203
288
  method_list.each do |method_name|
204
289
  it "- responds to ##{method_name}" do
205
- Base.new.should respond_to(method_name)
290
+ Base.new(:string_io_test).should respond_to(method_name)
206
291
  end
207
292
  end
208
293
  end
209
294
 
210
295
  describe "method stub with #not_yet_implemented! call" do
211
296
  it "raises NotYetImplemented" do
212
- ios = Base.new
297
+ ios = Base.new(:not_implemented)
213
298
  ios.instance_eval do
214
- def not_implemented_method
299
+ def not_implemented_method_a
300
+ not_yet_implemented!
301
+ end
302
+ def not_implemented_method_b
215
303
  not_yet_implemented! __method__, "#{__FILE__}:#{__LINE__}"
216
304
  end
217
305
  end
218
- expect { ios.not_implemented_method }.to raise_error(Base::NotYetImplemented)
306
+ expect { ios.not_implemented_method_a }.to raise_error(Errors::NotYetImplemented)
307
+ expect { ios.not_implemented_method_b }.to raise_error(Errors::NotYetImplemented)
308
+ expect { ios.not_implemented_method_c }.to raise_error(Errors::NotYetImplemented)
219
309
  end
220
310
  end
221
311
 
@@ -230,7 +320,7 @@ describe Base do
230
320
 
231
321
  Dir.mkdir(@tmp_path) unless File.exists?(@tmp_path)
232
322
  f = File.new(@tmp_true_file,'w')
233
- f.puts("true content")
323
+ f.puts "true content"
234
324
  f.close
235
325
  end
236
326
 
@@ -280,7 +370,7 @@ describe Base do
280
370
  context "file does not exist" do
281
371
  it "raises FileNotFoundError" do
282
372
  ios = Base.new(@tmp_false_file)
283
- expect { ios.load_from_file }.to raise_error(Base::FileNotFoundError)
373
+ expect { ios.load_from_file }.to raise_error(Errors::FileNotFoundError)
284
374
  end
285
375
  end
286
376
 
@@ -292,7 +382,7 @@ describe Base do
292
382
  context "with container name as default" do
293
383
  it "writes container into the file" do
294
384
  ios = Base.new(@tmp_save_file)
295
- ios.puts = "Test string"
385
+ ios.puts "Test string"
296
386
  ios.save_to_file.should be_true
297
387
  end
298
388
  end
@@ -300,7 +390,7 @@ describe Base do
300
390
  context "with custom name" do
301
391
  it "writes container into the file" do
302
392
  ios = Base.new(:different_name)
303
- ios.puts = "Test string"
393
+ ios.puts "Test string"
304
394
  ios.save_to_file(@tmp_save_file).should be_true
305
395
  end
306
396
  end
@@ -310,8 +400,8 @@ describe Base do
310
400
  context "path not accessible" do
311
401
  it "raises FileAccessError with corresponding reason" do
312
402
  ios = Base.new(@denied_path)
313
- ios.puts = "Test string"
314
- expect { ios.save_to_file }.to raise_error(Base::FileAccessError, /Reason/)
403
+ ios.puts "Test string"
404
+ expect { ios.save_to_file }.to raise_error(Errors::FileAccessError, /Reason/)
315
405
  end
316
406
  end
317
407