io_shuten 0.0.1.dev4 → 0.0.1.dev5

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 (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