tinkit 0.0.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (51) hide show
  1. data/LICENSE +176 -0
  2. data/README +11 -0
  3. data/Rakefile +75 -0
  4. data/lib/glue_envs/couchrest/couchrest_attachment_handler.rb +260 -0
  5. data/lib/glue_envs/couchrest/couchrest_files_mgr.rb +198 -0
  6. data/lib/glue_envs/couchrest_glue_env.rb +536 -0
  7. data/lib/glue_envs/files_mgr_base.rb +51 -0
  8. data/lib/glue_envs/filesystem/filesystem_files_mgr.rb +187 -0
  9. data/lib/glue_envs/filesystem_glue_env.rb +395 -0
  10. data/lib/glue_envs/mysql/mysql_files_mgr.rb +175 -0
  11. data/lib/glue_envs/mysql_glue_env.rb +428 -0
  12. data/lib/glue_envs/sdb_s3/sdb_s3_files_mgr.rb +314 -0
  13. data/lib/glue_envs/sdb_s3_glue_env.rb +248 -0
  14. data/lib/helpers/camel.rb +21 -0
  15. data/lib/helpers/filesystem_helpers.rb +27 -0
  16. data/lib/helpers/hash_helpers.rb +74 -0
  17. data/lib/helpers/log_helper.rb +34 -0
  18. data/lib/helpers/mime_types_new.rb +126 -0
  19. data/lib/helpers/old_more_open_struct.rb +28 -0
  20. data/lib/helpers/require_helper.rb +45 -0
  21. data/lib/helpers/tk_escape.rb +17 -0
  22. data/lib/midas/bufs_data_structure.rb +84 -0
  23. data/lib/midas/node_element_operations.rb +264 -0
  24. data/lib/tinkit.rb +38 -0
  25. data/lib/tinkit_base_node.rb +733 -0
  26. data/lib/tinkit_node_factory.rb +47 -0
  27. data/spec/couchrest_files_mgr_spec.rb +551 -0
  28. data/spec/couchrest_glue_spec.rb +246 -0
  29. data/spec/filesystem_files_mgr_spec.rb +236 -0
  30. data/spec/filesystem_glue_spec.rb +243 -0
  31. data/spec/filesystem_helpers_spec.rb +42 -0
  32. data/spec/helpers/bufs_node_builder.rb +17 -0
  33. data/spec/helpers/bufs_sample_dataset.rb +160 -0
  34. data/spec/helpers/bufs_test_environments.rb +81 -0
  35. data/spec/helpers/tmp_view_cleaner.rb +15 -0
  36. data/spec/lib_helpers/tk_escape_spec.rb +45 -0
  37. data/spec/mysql_files_mgr_spec.rb +250 -0
  38. data/spec/mysql_glue_spec.rb +214 -0
  39. data/spec/node_element_operations_spec.rb +392 -0
  40. data/spec/sdb_s3_files_mgr_spec/sdb_s3_files_mgr_spec1.rb +82 -0
  41. data/spec/sdb_s3_files_mgr_spec/sdb_s3_files_mgr_spec2.rb +68 -0
  42. data/spec/sdb_s3_files_mgr_spec/sdb_s3_files_mgr_spec3.rb +80 -0
  43. data/spec/sdb_s3_files_mgr_spec/sdb_s3_files_mgr_spec4.rb +110 -0
  44. data/spec/sdb_s3_files_mgr_spec/sdb_s3_files_mgr_spec5.rb +84 -0
  45. data/spec/sdb_s3_files_mgr_spec/sdb_s3_files_mgr_spec6.rb +83 -0
  46. data/spec/sdb_s3_files_mgr_spec/sdb_s3_files_mgr_spec7.rb +101 -0
  47. data/spec/sdb_s3_files_mgr_spec/sdb_s3_files_mgr_spec8.rb +92 -0
  48. data/spec/sdb_s3_files_mgr_spec/sdb_s3_files_mgr_spec_all.rb +266 -0
  49. data/spec/sdb_s3_glue_spec.rb +230 -0
  50. data/spec/tinkit_node_factory_spec.rb +1108 -0
  51. metadata +114 -0
@@ -0,0 +1,246 @@
1
+ #require helper for cleaner require statements
2
+ require File.join(File.expand_path(File.dirname(__FILE__)), '../lib/helpers/require_helper')
3
+
4
+ require Tinkit.glue 'couchrest_glue_env'
5
+
6
+ GlueTestDb = CouchRest.database!("http://127.0.0.1:5984/couchrest_glue_test")
7
+ GlueTestDb.compact!
8
+
9
+ describe CouchrestEnv::GlueEnv, "Initialization" do
10
+ before(:each) do
11
+ #set up env
12
+ persist_env = { :host => GlueTestDb.host,
13
+ :path => GlueTestDb.uri,
14
+ :user_id => 'couch_glue_user'}
15
+
16
+
17
+ @persist_env = {:name => :couchrest_glue_spec, :env => persist_env}
18
+
19
+ key_fields = { :required_keys => [:my_id],
20
+ :primary_key => :my_id }
21
+
22
+ @data_model_bindings = { :key_fields => key_fields,
23
+ :views => nil }
24
+
25
+ end
26
+
27
+ after(:each) do
28
+ GlueTestDb.delete!
29
+ end
30
+
31
+ it "should initialize properly" do
32
+ couchrest_glue_obj = CouchrestEnv::GlueEnv.new(@persist_env, @data_model_bindings)
33
+ #@data_dir = couchrest_glue_obj.user_datastore_location
34
+
35
+ #couchrest_glue_obj.dbh.connected?.should == true
36
+
37
+ couchrest_glue_obj.user_id.should == @persist_env[:env][:user_id]
38
+ couchrest_glue_obj.required_instance_keys.should == @data_model_bindings[:key_fields][:required_keys]
39
+ couchrest_glue_obj.required_save_keys.should == @data_model_bindings[:key_fields][:required_keys]
40
+ couchrest_glue_obj.node_key.should == @data_model_bindings[:key_fields][:primary_key]
41
+ required_metadata_keys = [couchrest_glue_obj.version_key,
42
+ couchrest_glue_obj.persist_layer_key,
43
+ couchrest_glue_obj.namespace_key]
44
+ (couchrest_glue_obj.metadata_keys & required_metadata_keys).sort.should == required_metadata_keys.sort
45
+ path = @persist_env[:env][:path]
46
+ user_id = @persist_env[:env][:user_id]
47
+ #p GlueTestDb.to_s
48
+ couchrest_glue_obj.user_datastore_location.should == user_id #?
49
+ couchrest_glue_obj._files_mgr_class.class.should_not == nil #The file manager class will handle file attachments
50
+ end
51
+
52
+ end
53
+
54
+
55
+ describe CouchrestEnv::GlueEnv, "Persistent Layer Basic Operations" do
56
+
57
+ before(:each) do
58
+ #set up env
59
+ persist_env = { :host => GlueTestDb.host,
60
+ :path => GlueTestDb.uri,
61
+ :user_id => 'couch_glue_user'}
62
+
63
+ #name isn't used in these specs, since that's used by the node factory to select the glue env
64
+ #but shown for clarity
65
+ @persist_env = {:name => :couchrest_glue_test, :env => persist_env}
66
+
67
+ key_fields = { :required_keys => [:my_id],
68
+ :primary_key => :my_id }
69
+
70
+ @data_model_bindings = { :key_fields => key_fields,
71
+ :views => nil }
72
+
73
+ @couchrest_glue_obj = CouchrestEnv::GlueEnv.new(@persist_env, @data_model_bindings)
74
+ end
75
+
76
+ after(:each) do
77
+ GlueTestDb.delete!
78
+ end
79
+
80
+ it "should persist data and be able to retrieve it" do
81
+ @couchrest_glue_obj.should_not == nil
82
+ #:id was defined as the primary key
83
+ data1 = {:my_id => "test_id1", :data => "test data"}
84
+ empty_data = @couchrest_glue_obj.get(data1[:my_id]) #hasn't been saved yet
85
+ empty_data.should == nil
86
+ @couchrest_glue_obj.save(data1)
87
+ #Don't use native get_attributes, use obj's get, it will block until save is finished
88
+ persisted_data = @couchrest_glue_obj.get(data1[:my_id])
89
+ persisted_data.should_not == nil
90
+ #puts "Persisted data for my_id: #{persisted_data}"
91
+ persisted_data[:my_id].should == data1[:my_id]
92
+ persisted_data[:data].should == data1[:data]
93
+ end
94
+
95
+ it "should be able to delete data" do
96
+ data1 = {:my_id => "test_id1", :data => "test data1"}
97
+ data2 = {:my_id => "test_id2", :data => "test data2"}
98
+ @couchrest_glue_obj.save(data1)
99
+ @couchrest_glue_obj.save(data2)
100
+ persisted_data1 = @couchrest_glue_obj.get(data1[:my_id])
101
+ persisted_data2 = @couchrest_glue_obj.get(data2[:my_id])
102
+ persisted_data1[:data].should == "test data1"
103
+ persisted_data2[:data].should == "test data2"
104
+ @couchrest_glue_obj.destroy_node({:my_id => data2[:my_id]})
105
+ persisted_data1 = @couchrest_glue_obj.get(data1[:my_id])
106
+ persisted_data2 = @couchrest_glue_obj.get(data2[:my_id])
107
+ persisted_data1[:data].should == "test data1"
108
+ persisted_data2.should == nil
109
+ end
110
+ end
111
+
112
+
113
+ describe CouchrestEnv::GlueEnv, "Persistent Layer Collection Operations" do
114
+
115
+ before(:each) do
116
+ #set up env
117
+ persist_env = { :host => GlueTestDb.host,
118
+ :path => GlueTestDb.uri,
119
+ :user_id => 'couch_glue_user'}
120
+
121
+ #name isn't used in these specs, since that's used by the node factory to select the glue env
122
+ #but shown for clarity
123
+ @persist_env = {:name => :couchrest_glue_test, :env => persist_env}
124
+
125
+ key_fields = { :required_keys => [:my_id],
126
+ :primary_key => :my_id }
127
+
128
+ @data_model_bindings = { :key_fields => key_fields,
129
+ :views => nil }
130
+
131
+ @couchrest_glue_obj = CouchrestEnv::GlueEnv.new(@persist_env, @data_model_bindings)
132
+ end
133
+
134
+ after(:each) do
135
+ #GlueTestDb.delete!
136
+ end
137
+
138
+ it "should be able to query all" do
139
+ data1 = {:my_id => "test_id1", :data => "test data1"}
140
+ data2 = {:my_id => "test_id2", :data => "test data2"}
141
+ @couchrest_glue_obj.save(data1)
142
+ @couchrest_glue_obj.save(data2)
143
+
144
+ results = @couchrest_glue_obj.query_all
145
+ results.size.should == 2
146
+ results.each do |raw_data|
147
+ case raw_data[:my_id]
148
+ when "test_id1"
149
+ raw_data[:data].should == "test data1"
150
+ when "test_id2"
151
+ raw_data[:data].should == "test data2"
152
+ else
153
+ raise "Unknown dataset #{raw_data.inspect}"
154
+ end#case
155
+ end#each
156
+ end
157
+
158
+ it "should be able to find matching data" do
159
+ data1 = {:my_id => "test_id1", :data => "test data1", :tags => ['a', 'b', 'c']}
160
+ data2 = {:my_id => "test_id2", :data => "test data2", :tags => ['c', 'd', 'e']}
161
+ data3 = {:my_id => "test_id3", :data => "test data2", :tags => ['c', 'b', 'z']}
162
+ data_list = [data1, data2, data3]
163
+ data_list.each {|data| @couchrest_glue_obj.save(data)}
164
+
165
+ result1 = @couchrest_glue_obj.find_nodes_where(:my_id, :equals, "test_id1")
166
+ result1.size.should == 1
167
+ result1.first[:my_id].should == "test_id1"
168
+
169
+ result2 = @couchrest_glue_obj.find_nodes_where(:my_id, :equals, "oops")
170
+ result2.should be_empty
171
+
172
+ result3 = @couchrest_glue_obj.find_nodes_where(:data, :equals, "test data2")
173
+ result3.size.should == 2
174
+ ["test_id2", "test_id3"].should include result3.first[:my_id]
175
+ ["test_id2", "test_id3"].should include result3.last[:my_id]
176
+
177
+ result4 = @couchrest_glue_obj.find_nodes_where(:tags, :equals, ['c', 'd', 'e'])
178
+ result4.size.should == 1
179
+ result4.first[:my_id].should == "test_id2"
180
+ end
181
+
182
+ it "should be able to find containting data" do
183
+ data1 = {:my_id => "test_id1", :data => "test data1", :tags => ['a', 'b', 'c']}
184
+ data2 = {:my_id => "test_id2", :data => "test data2", :tags => ['c', 'd', 'e']}
185
+ data3 = {:my_id => "test_id3", :data => "test data2", :tags => ['c', 'b', 'z']}
186
+ data_list = [data1, data2, data3]
187
+ data_list.each {|data| @couchrest_glue_obj.save(data)}
188
+
189
+ result1 = @couchrest_glue_obj.find_nodes_where(:my_id, :contains, "test_id2")
190
+ result1.size.should == 1
191
+ result1.first[:my_id].should == "test_id2"
192
+
193
+ result2 = @couchrest_glue_obj.find_nodes_where(:tags, :contains, "c")
194
+ result2.size.should == 3
195
+
196
+ result3 = @couchrest_glue_obj.find_nodes_where(:tags, :contains, "b")
197
+ result3.size.should == 2
198
+ ["test_id1", "test_id3"].should include result3.first[:my_id]
199
+ ["test_id1", "test_id3"].should include result3.last[:my_id]
200
+
201
+ result4 = @couchrest_glue_obj.find_nodes_where(:tags, :contains, "oops")
202
+ result4.should be_empty
203
+ end
204
+
205
+ it "should be able to delete in bulk" do
206
+ data1 = {:my_id => "test_id1", :data => "delete me"}
207
+ data2 = {:my_id => "test_id2", :data => "keep me"}
208
+ data3 = {:my_id => "test_id3", :data => "delete me too"}
209
+ @couchrest_glue_obj.save(data1)
210
+ @couchrest_glue_obj.save(data2)
211
+ @couchrest_glue_obj.save(data3)
212
+
213
+ results = @couchrest_glue_obj.query_all
214
+
215
+ results.each do |raw_data|
216
+ case raw_data[:my_id]
217
+ when "test_id1"
218
+ raw_data[:data].should == "delete me"
219
+ when "test_id2"
220
+ raw_data[:data].should == "keep me"
221
+ when "test_id3"
222
+ raw_data[:data].should == "delete me too"
223
+ else
224
+ raise "Unknown dataset"
225
+ end#case
226
+ end#each
227
+
228
+ raw_rcds_to_delete = [data1, data3]
229
+ @couchrest_glue_obj.destroy_bulk(raw_rcds_to_delete)
230
+
231
+ results = @couchrest_glue_obj.query_all
232
+ #puts "Destroy Bulk results: #{results.inspect}"
233
+ results.each do |raw_data|
234
+ case raw_data[:my_id]
235
+ when "test_id1"
236
+ raise "Oops should have been deleted"
237
+ when "test_id2"
238
+ raw_data[:data].should == "keep me"
239
+ when "test_id3"
240
+ raise "Oops should have been deleted"
241
+ else
242
+ raise "Unknown dataset"
243
+ end#case
244
+ end#each
245
+ end#it
246
+ end
@@ -0,0 +1,236 @@
1
+ #require helper for cleaner require statements
2
+ require File.join(File.expand_path(File.dirname(__FILE__)), '../lib/helpers/require_helper')
3
+ require Tinkit.glue 'filesystem/filesystem_files_mgr'
4
+
5
+ include FilesystemInterface
6
+ GlueEnvMock = Struct.new(:model_key, :user_datastore_location)
7
+
8
+ describe FilesMgr, "Setup and intialization" do
9
+
10
+ before(:all) do
11
+
12
+ @glue_env_mock = GlueEnvMock.new("_id", "/tmp/datastore_location")
13
+ @node_key = :_id
14
+
15
+ file1_data = "Example File1\nJust some text"
16
+ file2_data = "Example File2\nJust some more text"
17
+ file1_fname = "/tmp/example_file1.txt"
18
+ file2_fname = "/tmp/example_file2.txt"
19
+ files = {file1_fname => file1_data, file2_fname => file2_data}
20
+ files.each do |fname, data|
21
+ File.open(fname, 'w'){|f| f.write(data)}
22
+ end
23
+ @file_datas = [{:src_filename => file1_fname}, {:src_filename => file2_fname}]
24
+ @node1_data = {:_id => 'spec_test1', :data => 'stuff1'}
25
+ end
26
+
27
+ it "should initialize" do
28
+ node_key_value = @node1_data[@node_key]
29
+ attach_handler = FilesMgr.new(@glue_env_mock, node_key_value)
30
+
31
+ #note actual table is setup in glue_env, not file_mgr
32
+ attach_handler.attachment_location.should == "#{@glue_env_mock.user_datastore_location}/#{node_key_value}"
33
+ end
34
+ end
35
+
36
+ describe FilesMgr, "Basic Operations" do
37
+ before(:all) do
38
+ @user_datastore_location = "/tmp/datastore_location"
39
+ @file1_fname = "/tmp/example_file1.txt"
40
+ @file2_fname = "/tmp/example_file2.txt"
41
+ f1_bname = File.basename(@file1_fname)
42
+ f2_bname = File.basename(@file2_fname)
43
+ @file_stored_data = { f1_bname => File.open(@file1_fname, 'rb'){|f| f.read},
44
+ f2_bname =>File.open(@file2_fname, 'rb'){|f| f.read} }
45
+
46
+ @mock_key = :_id
47
+ @nodeMockClass = Struct.new(@mock_key, :my_GlueEnv)
48
+
49
+ @glue_env_mock = GlueEnvMock.new(@mock_key,
50
+ @user_datastore_location)
51
+
52
+ #set up table for spec
53
+
54
+ @file_datas = [{:src_filename => @file1_fname}, {:src_filename => @file2_fname}]
55
+ end
56
+
57
+
58
+ before(:each) do
59
+ @node1_data = {:_id => 'spec_test1', :data => 'stuff1'}
60
+ @node_mock = @nodeMockClass.new(@node1_data[@mock_key],
61
+ @glue_env_mock)
62
+
63
+ node_key_value = @node1_data[@mock_key]
64
+ @attach_handler = FilesMgr.new(@glue_env_mock, node_key_value)
65
+ #@attach_handler.subtract_files(nil, :all)
66
+ end
67
+
68
+ after(:all) do
69
+ FileUtils.rm_rf(@user_datastore_location)
70
+ @file_datas.each do |file_data|
71
+ FileUtils.rm(file_data[:src_filename])
72
+ end
73
+ end
74
+
75
+ it "should add and retrieve files" do
76
+ node = @node_mock
77
+
78
+ @file_datas.each do |file_data|
79
+ file_basename = File.basename(file_data[:src_filename])
80
+ data = @attach_handler.get_raw_data(node, file_basename)
81
+ data.should be_nil
82
+ end
83
+
84
+ #Add the Files
85
+ @attach_handler.add(node, @file_datas)
86
+
87
+ #Get the files and verify data
88
+ @file_datas.each do |file_data|
89
+ file_basename = File.basename(file_data[:src_filename])
90
+ data = @attach_handler.get_raw_data(node, file_basename)
91
+ data.should == @file_stored_data[file_basename]
92
+ end
93
+ end
94
+
95
+ it "should list attachment files" do
96
+ files = @attach_handler.list(@node_mock)
97
+ files.sort.should == @file_stored_data.keys.sort
98
+ end
99
+
100
+ it "should list metadata" do
101
+
102
+ md = @attach_handler.get_attachments_metadata(@node_mock)
103
+ md.should_not == nil
104
+ @file_datas.each do |file_data|
105
+ file_basename = File.basename(file_data[:src_filename])
106
+ each_md = md[file_basename.to_sym]
107
+ each_md.should_not == nil
108
+ each_md.keys.should include :content_type
109
+ each_md.keys.should include :file_modified
110
+
111
+ file_basename = File.basename(file_data[:src_filename])
112
+ md[file_basename.to_sym][:content_type].should =~ /^text\/plain/
113
+ time_str = md[file_basename.to_sym][:file_modified]
114
+ Time.parse(time_str).should > Time.now - 1 #should have been modified less than a second ago
115
+ end
116
+ end
117
+
118
+ it "should be well behaved adding more files" do
119
+ node = @node_mock
120
+
121
+ #Get the original files and verify data
122
+ @file_datas.each do |file_data|
123
+ file_basename = File.basename(file_data[:src_filename])
124
+ data = @attach_handler.get_raw_data(node, file_basename)
125
+ data.should == @file_stored_data[file_basename]
126
+ end
127
+
128
+ #create some more files
129
+ file1_data = "Example File1\nNEW!! text"
130
+ file3_data = "Example File3\nYet more text"
131
+ file4_data = "Example File4\nand more text"
132
+ file3_fname = "/tmp/example_file3.txt"
133
+ file4_fname = "/tmp/example_file4.txt"
134
+ files = {@file1_fname => file1_data, file3_fname => file3_data, file4_fname => file4_data}
135
+ files.each do |fname, data|
136
+ File.open(fname, 'w'){|f| f.write(data)}
137
+ end
138
+ file1_data.should == File.open(@file1_fname){|f| f.read}
139
+ @file_datas2 = [{:src_filename => @file1_fname},
140
+ {:src_filename => file3_fname},
141
+ {:src_filename => file4_fname}]
142
+
143
+ #add them
144
+ @attach_handler.add(node, @file_datas2)
145
+
146
+ #Check the unchanged file (file2)
147
+ file2_basename = File.basename(@file2_fname)
148
+ data2 = @attach_handler.get_raw_data(node, file2_basename)
149
+ data2.should == @file_stored_data[file2_basename]
150
+
151
+ #Get the changed files and verify it is the new data
152
+ file1_basename = File.basename(@file1_fname)
153
+ data1 = @attach_handler.get_raw_data(node, file1_basename)
154
+ data1.should == file1_data
155
+
156
+ file3_basename = File.basename(file3_fname)
157
+ data3 = @attach_handler.get_raw_data(node, file3_basename)
158
+ data3.should == file3_data
159
+
160
+ file4_basename = File.basename(file4_fname)
161
+ data4 = @attach_handler.get_raw_data(node, file4_basename)
162
+ data4.should == file4_data
163
+ end
164
+
165
+ it "should delete files" do
166
+ node = @node_mock
167
+ files_to_delete = [@file1_fname, @file2_fname]
168
+ #they should exist in the node
169
+ files_to_delete.each do |fname|
170
+ file_basename = File.basename(fname)
171
+ data = @attach_handler.get_raw_data(node, file_basename)
172
+ data.should match /^Example File/
173
+ end
174
+
175
+ basenames_to_delete = files_to_delete.map{|f| File.basename(f)}
176
+ @attach_handler.subtract(node, basenames_to_delete)
177
+
178
+ files_to_delete.each do |fname|
179
+ file_basename = File.basename(fname)
180
+ data = @attach_handler.get_raw_data(node, file_basename)
181
+ data.should be_nil
182
+ end
183
+ end
184
+
185
+ it "should add attachments from the raw data" do
186
+ node = @node_mock
187
+
188
+ raw_data = "Example File3\nYet more text"
189
+ content_type = "text/plain"
190
+ modified_at = Time.now.to_s
191
+ att_name = "example_raw_data.txt"
192
+
193
+
194
+
195
+ #Add the Raw Data
196
+ @attach_handler.add_raw_data(node, att_name, content_type, raw_data, modified_at)
197
+
198
+ #Get the files and verify data
199
+
200
+ data = @attach_handler.get_raw_data(node, att_name)
201
+ md = @attach_handler.get_attachments_metadata(node)[att_name.to_sym]
202
+
203
+ data.should == raw_data
204
+ md[:content_type].should == content_type
205
+ md[:file_modified].should == modified_at
206
+ end
207
+
208
+ it "should delete all (subtract_all) files" do
209
+ node = @node_mock
210
+
211
+ #create some more attachments
212
+ del_data = {}
213
+ del_data["del_data1"] = "my life will be short"
214
+ del_data["del_data2"] = "alas too short"
215
+
216
+ #add the attachments
217
+ del_data.each do |name, data|
218
+ @attach_handler.add_raw_data(node, name, "text/plain", data, Time.now.to_s)
219
+ end
220
+
221
+ #verify it's there
222
+ del_data.each do |name, data|
223
+ stored_data = @attach_handler.get_raw_data(node, name)
224
+ stored_data.should == data
225
+ end
226
+
227
+ #delete it all
228
+ @attach_handler.subtract(node, :all)
229
+
230
+ #verify it'snot there
231
+ del_data.each do |name, data|
232
+ stored_data = @attach_handler.get_raw_data(node, name)
233
+ stored_data.should be_nil
234
+ end
235
+ end
236
+ end