orientdb-binary 0.6.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (59) hide show
  1. checksums.yaml +7 -0
  2. data/.gitignore +2 -0
  3. data/Gemfile +5 -0
  4. data/LICENSE.txt +22 -0
  5. data/README.md +29 -0
  6. data/Rakefile +64 -0
  7. data/lib/orientdb_binary.rb +25 -0
  8. data/lib/orientdb_binary/base.rb +40 -0
  9. data/lib/orientdb_binary/config.rb +5 -0
  10. data/lib/orientdb_binary/connection.rb +17 -0
  11. data/lib/orientdb_binary/database.rb +24 -0
  12. data/lib/orientdb_binary/database_operations/base_operations.rb +70 -0
  13. data/lib/orientdb_binary/database_operations/data_cluster.rb +116 -0
  14. data/lib/orientdb_binary/database_operations/data_segment.rb +31 -0
  15. data/lib/orientdb_binary/database_operations/query.rb +58 -0
  16. data/lib/orientdb_binary/database_operations/record.rb +105 -0
  17. data/lib/orientdb_binary/database_operations/transaction.rb +8 -0
  18. data/lib/orientdb_binary/operation_types.rb +51 -0
  19. data/lib/orientdb_binary/parser/deserializer.rb +161 -0
  20. data/lib/orientdb_binary/parser/serializer.rb +83 -0
  21. data/lib/orientdb_binary/protocols/base.rb +42 -0
  22. data/lib/orientdb_binary/protocols/bindata_primitives.rb +46 -0
  23. data/lib/orientdb_binary/protocols/command.rb +166 -0
  24. data/lib/orientdb_binary/protocols/config_get.rb +22 -0
  25. data/lib/orientdb_binary/protocols/config_list.rb +24 -0
  26. data/lib/orientdb_binary/protocols/config_set.rb +22 -0
  27. data/lib/orientdb_binary/protocols/connect.rb +26 -0
  28. data/lib/orientdb_binary/protocols/datacluster_add.rb +26 -0
  29. data/lib/orientdb_binary/protocols/datacluster_count.rb +26 -0
  30. data/lib/orientdb_binary/protocols/datacluster_datarange.rb +23 -0
  31. data/lib/orientdb_binary/protocols/datacluster_drop.rb +22 -0
  32. data/lib/orientdb_binary/protocols/datacluster_lh_cluster_is_used.rb +20 -0
  33. data/lib/orientdb_binary/protocols/datasegment_add.rb +24 -0
  34. data/lib/orientdb_binary/protocols/datasegment_drop.rb +23 -0
  35. data/lib/orientdb_binary/protocols/db_close.rb +16 -0
  36. data/lib/orientdb_binary/protocols/db_countrecords.rb +20 -0
  37. data/lib/orientdb_binary/protocols/db_create.rb +23 -0
  38. data/lib/orientdb_binary/protocols/db_drop.rb +22 -0
  39. data/lib/orientdb_binary/protocols/db_exist.rb +23 -0
  40. data/lib/orientdb_binary/protocols/db_freeze.rb +21 -0
  41. data/lib/orientdb_binary/protocols/db_list.rb +26 -0
  42. data/lib/orientdb_binary/protocols/db_open.rb +43 -0
  43. data/lib/orientdb_binary/protocols/db_release.rb +21 -0
  44. data/lib/orientdb_binary/protocols/db_reload.rb +26 -0
  45. data/lib/orientdb_binary/protocols/db_size.rb +20 -0
  46. data/lib/orientdb_binary/protocols/errors.rb +28 -0
  47. data/lib/orientdb_binary/protocols/record_create.rb +35 -0
  48. data/lib/orientdb_binary/protocols/record_delete.rb +25 -0
  49. data/lib/orientdb_binary/protocols/record_load.rb +65 -0
  50. data/lib/orientdb_binary/protocols/record_update.rb +27 -0
  51. data/lib/orientdb_binary/protocols/shutdown.rb +21 -0
  52. data/lib/orientdb_binary/server.rb +71 -0
  53. data/orientdb-binary.gemspec +26 -0
  54. data/test/database/test_database.rb +193 -0
  55. data/test/database/test_deserializer.rb +140 -0
  56. data/test/database/test_serializer.rb +55 -0
  57. data/test/server/test_server.rb +73 -0
  58. data/test/test_helper.rb +9 -0
  59. metadata +162 -0
@@ -0,0 +1,65 @@
1
+ module OrientdbBinary
2
+ module Protocols
3
+
4
+ class RecordLoad < BinData::Record
5
+ include OrientdbBinary::Protocols::Base
6
+
7
+ endian :big
8
+
9
+ int8 :operation, value: OrientdbBinary::OperationTypes::REQUEST_RECORD_LOAD
10
+ int32 :session
11
+
12
+ int16 :cluster_id
13
+ int64 :cluster_position
14
+ protocol_string :fetch_plan
15
+ int8 :ignore_cache
16
+ int8 :load_tombstones
17
+ end
18
+
19
+ class RecordLoadAnswer < BinData::Record
20
+ endian :big
21
+
22
+ int32 :session
23
+ int8 :payload_status
24
+ array :collection, initial_length: :payload_status do
25
+ protocol_string :content
26
+ int32 :version
27
+ record_type :record_type
28
+ end
29
+
30
+ array :prefetched_records, read_until: -> {element.payload_status == 0}, onlyif: -> {payload_status > 0} do
31
+ int8 :payload_status
32
+ int16 :marker, onlyif: -> {payload_status > 0}
33
+ record_type :record_type, onlyif: -> {payload_status > 0}
34
+ int16 :cluster_id, onlyif: -> {payload_status > 0}
35
+ int64 :position, onlyif: -> {payload_status > 0}
36
+ int32 :version, onlyif: -> {payload_status > 0}
37
+ protocol_string :content, onlyif: -> {payload_status > 0}
38
+ end
39
+
40
+ def process(options)
41
+ colls = self.collection.map do |record|
42
+ opts = {
43
+ :@rid => "##{options[:cluster_id]}:#{options[:cluster_position]}",
44
+ :@version => record[:version],
45
+ :@type => record[:record_type]
46
+ }
47
+ OrientdbBinary::Parser::Deserializer.new().deserialize(record[:content], opts)
48
+ end
49
+
50
+ prefetched = self.prefetched_records.map do |record|
51
+ if record[:payload_status] > 0
52
+ opts = {
53
+ :@rid => "##{record[:cluster_id]}:#{record[:position]}",
54
+ :@version => record[:version],
55
+ :@type => record[:record_type]
56
+ }
57
+ OrientdbBinary::Parser::Deserializer.new().deserialize(record[:content], opts)
58
+ end
59
+ end
60
+
61
+ {collection: colls, prefetched_records: prefetched.delete_if {|rec| !rec}}
62
+ end
63
+ end
64
+ end
65
+ end
@@ -0,0 +1,27 @@
1
+ module OrientdbBinary
2
+ module Protocols
3
+
4
+ class RecordUpdate < BinData::Record
5
+ include OrientdbBinary::Protocols::Base
6
+
7
+ endian :big
8
+
9
+ int8 :operation, value: OrientdbBinary::OperationTypes::REQUEST_RECORD_UPDATE
10
+ int32 :session
11
+
12
+ int16 :cluster_id
13
+ int64 :cluster_position
14
+ protocol_string :record_content
15
+ int32 :record_version
16
+ int8 :record_type
17
+ int8 :mode
18
+ end
19
+
20
+ class RecordUpdateAnswer < BinData::Record
21
+ endian :big
22
+
23
+ int32 :session
24
+ int32 :record_version
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,21 @@
1
+ module OrientdbBinary
2
+ module Protocols
3
+
4
+ class Shutdown < BinData::Record
5
+ include OrientdbBinary::Protocols::Base
6
+
7
+ endian :big
8
+
9
+ int8 :operation, value: OrientdbBinary::OperationTypes::REQUEST_SHUTDOWN
10
+ int32 :session
11
+ protocol_string :user
12
+ protocol_string :password
13
+ end
14
+
15
+ class ShutdownAnswer < BinData::Record
16
+ endian :big
17
+
18
+ rest :message
19
+ end
20
+ end
21
+ end
@@ -0,0 +1,71 @@
1
+ require 'orientdb_binary/protocols/connect'
2
+ require 'orientdb_binary/protocols/db_exist'
3
+ require 'orientdb_binary/protocols/db_create'
4
+ require 'orientdb_binary/protocols/db_drop'
5
+ require 'orientdb_binary/protocols/db_freeze'
6
+ require 'orientdb_binary/protocols/db_release'
7
+ require 'orientdb_binary/protocols/shutdown'
8
+ require 'orientdb_binary/protocols/config_list'
9
+ require 'orientdb_binary/protocols/config_get'
10
+ require 'orientdb_binary/protocols/config_set'
11
+
12
+ module OrientdbBinary
13
+ class Server < OrientdbBinary::OrientdbBase
14
+ def self.connect(options)
15
+ Server.new(options)
16
+ end
17
+
18
+ def connect(args)
19
+ connection = OrientdbBinary::Protocols::Connect.new(
20
+ protocol: protocol,
21
+ user: args[:user],
22
+ password: args[:password]
23
+ ).process(socket)
24
+ @session = connection[:session] || OrientdbBinary::OperationTypes::NEW_SESSION
25
+ @connected = true if @session > OrientdbBinary::OperationTypes::NEW_SESSION
26
+ connection
27
+ end
28
+
29
+ def db_exists?(name)
30
+ answer = OrientdbBinary::Protocols::DbExist.new(session: session, database: name).process(socket)
31
+ answer[:exists] == 1
32
+ end
33
+
34
+ def db_create(name, type, storage)
35
+ OrientdbBinary::Protocols::DbCreate.new(session: session, name: name, type: type, storage: storage).process(socket)
36
+ end
37
+
38
+ def db_drop(name, storage)
39
+ OrientdbBinary::Protocols::DbDrop.new(session: session, name: name, storage: storage).process(socket)
40
+ end
41
+
42
+ def list
43
+ OrientdbBinary::Protocols::DbList.new(session: session).process(socket).process
44
+ end
45
+
46
+ def db_freeze(name, storage)
47
+ OrientdbBinary::Protocols::DbFreeze.new(session: session, name: name, storage: storage).process(socket)
48
+ end
49
+
50
+ def db_release(name, storage)
51
+ OrientdbBinary::Protocols::DbRelease.new(session: session, name: name, storage: storage).process(socket)
52
+ end
53
+
54
+ def get_config(key)
55
+ OrientdbBinary::Protocols::ConfigGet.new(session: session, option_key: key).process(socket)
56
+ end
57
+
58
+ def set_config(key, value)
59
+ OrientdbBinary::Protocols::ConfigSet.new(session: session, option_key: key.to_s, option_value: value.to_s).process(socket)
60
+ end
61
+
62
+ def config_list
63
+ OrientdbBinary::Protocols::ConfigList.new(session: session).process(socket)
64
+ end
65
+
66
+ def shutdown
67
+ OrientdbBinary::Protocols::Shutdown.new(session: session, user: @options[:user], password: @options[:password]).process(socket)
68
+ end
69
+
70
+ end
71
+ end
@@ -0,0 +1,26 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'orientdb_binary/config'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "orientdb-binary"
8
+ spec.version = OrientdbBinary::VERSION
9
+ spec.authors = ["Michal Ostrowski"]
10
+ spec.email = ["ostrowski.michal@gmail.com"]
11
+ spec.summary = %q{OrientDB native client for Ruby 2}
12
+ spec.description = %q{Graph Database OrientDB native client for Ruby}
13
+ spec.homepage = "http://orientdb-binary.espresse.net"
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0")
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_development_dependency "bundler", "~> 1.5"
22
+ spec.add_development_dependency "rake", '~> 0.9'
23
+ spec.add_development_dependency "simplecov", '~> 0.8'
24
+
25
+ spec.add_runtime_dependency "bindata", "~> 1.8"
26
+ end
@@ -0,0 +1,193 @@
1
+ require 'minitest/spec'
2
+ require 'minitest/autorun'
3
+
4
+ describe OrientdbBinary::Database do
5
+ before do
6
+ @server = OrientdbBinary::Server.new(TestHelper::SERVER)
7
+ @server.connect(TestHelper::SERVER_USER)
8
+
9
+ if @server.db_exists? TestHelper::TEST_DB[:db]
10
+ @server.db_drop TestHelper::TEST_DB[:db], TestHelper::TEST_DB[:storage]
11
+ end
12
+ @server.db_create(TestHelper::TEST_DB[:db], 'document', TestHelper::TEST_DB[:storage])
13
+
14
+ @db = OrientdbBinary::Database.new(TestHelper::SERVER)
15
+ @open = @db.open(TestHelper::TEST_DB.merge(TestHelper::TEST_DB_USER))
16
+ end
17
+
18
+ after do
19
+ if @server.db_exists? TestHelper::TEST_DB[:db]
20
+ @server.db_drop TestHelper::TEST_DB[:db], TestHelper::TEST_DB[:storage]
21
+ end
22
+ @db.disconnect
23
+ assert !@db.connected?
24
+ @server.disconnect
25
+ end
26
+
27
+ describe 'database' do
28
+ it "should be opened" do
29
+ assert @db.connected?
30
+ end
31
+
32
+ it "should have info about build" do
33
+ assert @open[:orientdb_release].length > 0
34
+ end
35
+
36
+ it "should count records" do
37
+ assert @db.count_records[:count_records] == 12 #(6 OIdentity + 3 OUser + 3 ORole)
38
+ end
39
+
40
+ it "should reload database" do
41
+ answer = @db.reload()
42
+ assert_equal answer[:num_of_clusters], answer[:clusters].length
43
+ end
44
+
45
+ it "should add datasegment" do
46
+ assert @db.add_datasegment(name: 'test_datasegment', location: 'test_location')[:segment_id] > 0
47
+ end
48
+
49
+ it "should add datasegment providing name only" do
50
+ assert @db.add_datasegment(name: 'test_datasegment_1')[:segment_id] > 0
51
+ end
52
+
53
+ it "should drop datasegment" do
54
+ @db.add_datasegment(name: 'test_datasegment', location: 'test_location')
55
+ assert @db.drop_datasegment(name: 'test_datasegment')[:succeed]
56
+ end
57
+
58
+ describe 'datacluster' do
59
+ before do
60
+ @db.add_datasegment(name: 'test_datasegment', location: 'test_location')
61
+ @datacluster = @db.add_datacluster(type: 'MEMORY', name: 'testmemory', location: 'test_location', datasegment_name: 'test_datasegment')
62
+ end
63
+
64
+ after do
65
+ @db.drop_datacluster(cluster_id: @datacluster[:cluster_id]) if @datacluster
66
+ end
67
+
68
+ it "should add" do
69
+ assert @db.reload()[:clusters].last[:cluster_name] == "testmemory"
70
+ end
71
+
72
+ it "should add datacluster without optional params" do
73
+ datacluster = @db.add_datacluster(name: 'test_cluster', datasegment_name: 'default')
74
+ assert @db.reload()[:clusters].last[:cluster_name] == "test_cluster"
75
+ @db.drop_datacluster(cluster_id: datacluster[:cluster_id])
76
+ end
77
+
78
+ it "should drop" do
79
+ @db.drop_datacluster(cluster_id: @datacluster[:cluster_id])
80
+ @db.reload()[:clusters]
81
+ assert @db.reload()[:clusters].last[:cluster_name] != "testmemory"
82
+ @datacluster = nil
83
+ end
84
+
85
+ it "should drop datacluster when providing name of it" do
86
+ @db.drop_datacluster(cluster_name: 'testmemory')
87
+ end
88
+
89
+ it "should count" do
90
+ assert_equal 6, @db.count_datacluster(cluster_ids: [0,1,2])[:records_in_clusters]
91
+ end
92
+
93
+ it "should count clusters by name" do
94
+ assert_equal 6, @db.count_datacluster(cluster_names: ['internal','index','manindex'])[:records_in_clusters]
95
+ end
96
+
97
+ it "should return datarange" do
98
+ range = @db.datarange_datacluster(cluster_id: 0)
99
+ assert_equal 0, range[:record_id_begin]
100
+ assert_equal 2, range[:record_id_end]
101
+ end
102
+
103
+ it "should return datarange" do
104
+ range = @db.datarange_datacluster(cluster_name: 'internal')
105
+ assert_equal 0, range[:record_id_begin]
106
+ assert_equal 2, range[:record_id_end]
107
+ end
108
+ end
109
+
110
+ describe "record" do
111
+ it "should be possible to add it" do
112
+ params = {
113
+ datasegment_id: -1,
114
+ cluster_id: 5,
115
+ record_content: "OUser@name:\"other_admin\",password:\"{SHA-256}8C6976E5B5410415BDE908BD4DEE15DFB167A9C873FC4BB8A81F6F2AB448A918\",status:\"ACTIVE\",roles:<#4:0>",
116
+ record_type: 100,
117
+ mode: 0
118
+ }
119
+ record = @db.create_record(params)
120
+ match = record[:@rid].match /#(?<version>\d+):(?<position>\d+)/
121
+ assert match[:position].to_i > 0
122
+ end
123
+
124
+ it "should be possible to add object with class" do
125
+ record = {
126
+ :@class => "OUser",
127
+ name: "other_admin",
128
+ password: "{SHA-256}8C6976E5B5410415BDE908BD4DEE15DFB167A9C873FC4BB8A81F6F2AB448A918",
129
+ status: "ACTIVE",
130
+ roles: (Set.new ["#4:0"])
131
+ }
132
+ record = @db.create_record_from_object(record)
133
+ match = record[:@rid].match /#(?<version>\d+):(?<position>\d+)/
134
+ assert match[:position].to_i == 0 #cluster_id is set to default and s there is no records position is to 0
135
+ end
136
+
137
+ it "should be possible to add object with cluster" do
138
+ record = {
139
+ :@class => "OUser",
140
+ :@cluster => "ouser",
141
+ name: "other_admin",
142
+ password: "{SHA-256}8C6976E5B5410415BDE908BD4DEE15DFB167A9C873FC4BB8A81F6F2AB448A918",
143
+ status: "ACTIVE",
144
+ roles: (Set.new ["#4:0"])
145
+ }
146
+ record = @db.create_record_from_object(record)
147
+ match = record[:@rid].match /#(?<version>\d+):(?<position>\d+)/
148
+ assert match[:position].to_i > 0
149
+ end
150
+
151
+ it "should be able to read content" do
152
+ record = @db.load_record(cluster_id: 5, cluster_position: 0, fetch_plan: "*:0", ignore_cache: 1, load_tombstones: 0)
153
+ assert record[:collection].length > 0
154
+ end
155
+
156
+ it "should be able to load record by providing rid only" do
157
+ record = @db.load_record(rid: "#5:0")
158
+ assert record[:collection].length > 0
159
+ end
160
+
161
+ it "should be able to pre-fetch linked collection" do
162
+ record = @db.load_record(cluster_id: 5, cluster_position: 0, fetch_plan: "*:-1", ignore_cache: 1, load_tombstones: 0)
163
+ assert_equal record[:prefetched_records].length, 1
164
+ end
165
+
166
+ it "should be able to update" do
167
+ params = {
168
+ cluster_id: 5,
169
+ cluster_position: 0,
170
+ record_content: "OUser@name:\"other_admin\",password:\"{SHA-256}8C6976E5B5410415BDE908BD4DEE15DFB167A9C873FC4BB8A81F6F2AB448A918\",status:\"ACTIVE\",roles:<#4:0>",
171
+ record_version: 0,
172
+ record_type: 100,
173
+ mode: 0
174
+ }
175
+ record = @db.update_record(params)
176
+ assert_equal record[:record_version], 1
177
+ end
178
+
179
+ describe "delete" do
180
+ before do
181
+ @delete_action = @db.delete_record(cluster_id: 5, cluster_position: 0, record_version: 0, mode: 0)
182
+ end
183
+ it "should hav epayload status set to 1" do
184
+ assert_equal 1, @delete_action[:payload_status]
185
+ end
186
+
187
+ it "should not load record" do
188
+ assert_equal 0, @db.load_record(cluster_id: 5, cluster_position: 0, fetch_plan: "*:-1", ignore_cache: 1, load_tombstones: 0)[:collection].length
189
+ end
190
+ end
191
+ end
192
+ end
193
+ end
@@ -0,0 +1,140 @@
1
+ require 'minitest/spec'
2
+ require 'minitest/autorun'
3
+
4
+ describe OrientdbBinary::Parser do
5
+
6
+ describe 'Deserializer' do
7
+ before do
8
+ @parser = OrientdbBinary::Parser::Deserializer.new
9
+ end
10
+
11
+ describe "parsing sets" do
12
+ before do
13
+ record = "DocWithSets@a_set:<\"one\",\"two\",3,#12:1>"
14
+ @result = @parser.deserialize_document(record)
15
+ end
16
+
17
+ it "should be Set" do
18
+ assert_equal @result[:a_set].class, Set
19
+ end
20
+
21
+ it "should find 4 elements" do
22
+ assert_equal @result[:a_set].length, 4
23
+ end
24
+
25
+ it "should parse string in set" do
26
+ assert @result[:a_set].include? "one"
27
+ end
28
+
29
+ it "should parse integer in set" do
30
+ assert @result[:a_set].include? 3
31
+ end
32
+
33
+ it "should parse rid in set" do
34
+ assert @result[:a_set].include? "#12:1"
35
+ end
36
+ end
37
+
38
+ describe "parsing primitives" do
39
+ before do
40
+ record = "@date:#{Date.today.to_datetime.to_time.to_i}a,time:#{DateTime.now.to_time.to_i}t,name:\"HEY BO DIDDLEY\",song_type:\"cover\",is_active:true,performances:5,stars:5.234f,price:12c,type:\"song\",out_followed_by:<#11:0,#11:1,#11:2,#11:3,#11:4>,out_written_by:#9:7,out_sung_by:#9:8,in_followed_by:<#11:10,#11:150,#11:2578,#11:5574> "
41
+ @result = @parser.deserialize_document(record)
42
+ end
43
+
44
+ it "should parse string as String" do
45
+ assert @result[:name].is_a? String
46
+ end
47
+
48
+ it "should parse string" do
49
+ assert_equal @result[:name], "HEY BO DIDDLEY"
50
+ end
51
+
52
+ it "should parse int as integer" do
53
+ assert_equal @result[:performances], 5
54
+ end
55
+
56
+ it "should parse date" do
57
+ assert @result[:date].is_a? Date
58
+ end
59
+
60
+ it "should parse datetime" do
61
+ assert @result[:time].is_a? DateTime
62
+ end
63
+
64
+ it "should parse float" do
65
+ assert @result[:stars].is_a? Float
66
+ end
67
+
68
+ it "should parse big decimals" do
69
+ assert @result[:price].is_a? BigDecimal
70
+ end
71
+
72
+ it "should parse booleans" do
73
+ assert @result[:is_active].is_a? TrueClass
74
+ end
75
+ end
76
+
77
+ describe "parsing hashes" do
78
+ before do
79
+ record = "Hash@html:{\"path\":\"html/layout\"}"
80
+ @result = @parser.deserialize_document(record)
81
+ end
82
+
83
+ it "should parse hash as Hash" do
84
+ assert @result.is_a? Hash
85
+ end
86
+
87
+ it "should parse hash parameters" do
88
+ assert_equal @result[:html][:path], "html/layout"
89
+ end
90
+ end
91
+
92
+ describe "parsing arrays" do
93
+ before do
94
+ record = "Array@array:[\"path\",{hash:{path:\"html/layout\"}},2]"
95
+ @result = @parser.deserialize_document(record)
96
+ end
97
+
98
+ it "should parse array" do
99
+ assert @result[:array].is_a? Array
100
+ end
101
+
102
+ it "should find 3 elements" do
103
+ assert_equal @result[:array].length, 3
104
+ end
105
+
106
+ describe "array elements" do
107
+ it "should parse string" do
108
+ assert_equal @result[:array][0], "path"
109
+ end
110
+
111
+ it "should parse hash" do
112
+ assert @result[:array][1].is_a? Hash
113
+ end
114
+
115
+ it "should parse integers" do
116
+ assert @result[:array][2].is_a? Integer
117
+ end
118
+ end
119
+ end
120
+
121
+ describe "parsing documents" do
122
+ before do
123
+ record = "schemaVersion:4,classes:[(name:\"OUser\",shortName:,defaultClusterId:4,clusterIds:[4],overSize:0.0f,strictMode:false,properties:[(name:\"password\",type:7,mandatory:true,notNull:true,min:,max:,regexp:,linkedClass:,linkedType:),(name:\"name\",type:7,mandatory:true,notNull:true,min:,max:,regexp:,linkedClass:,linkedType:),(name:\"roles\",type:15,mandatory:false,notNull:false,min:,max:,regexp:,linkedClass:\"ORole\",linkedType:)]),(name:\"ORole\",shortName:,defaultClusterId:3,clusterIds:[3],overSize:0.0f,strictMode:false,properties:[(name:\"mode\",type:17,mandatory:false,notNull:false,min:,max:,regexp:,linkedClass:,linkedType:),(name:\"rules\",type:12,mandatory:false,notNull:false,min:,max:,regexp:,linkedClass:,linkedType:17),(name:\"name\",type:7,mandatory:true,notNull:true,min:,max:,regexp:,linkedClass:,linkedType:)])]"
124
+ @result = @parser.deserialize_document(record)
125
+ end
126
+
127
+ it "should parse documents" do
128
+ assert @result[:classes][0][:@type], "d"
129
+ end
130
+
131
+ it "should parse embedded documents" do
132
+ assert @result[:classes][0][:properties][0][:@type], "d"
133
+ end
134
+
135
+ it "should parse empty objects" do
136
+ assert_equal @result[:classes][0][:properties][0][:max], nil
137
+ end
138
+ end
139
+ end
140
+ end