rod 0.6.1 → 0.6.2

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 (50) hide show
  1. data/.gitignore +7 -0
  2. data/{README → README.rdoc} +33 -2
  3. data/Rakefile +7 -2
  4. data/changelog.txt +13 -0
  5. data/contributors.txt +2 -0
  6. data/features/append.feature +221 -0
  7. data/features/assoc_indexing.feature +66 -0
  8. data/features/basic.feature +199 -0
  9. data/features/collection.feature +171 -0
  10. data/features/flat_indexing.feature +140 -0
  11. data/features/fred.feature +49 -0
  12. data/features/inheritence.feature +211 -0
  13. data/features/muliple_db.feature +113 -0
  14. data/features/relationships.feature +195 -0
  15. data/features/segmented_indexing.feature +172 -0
  16. data/features/steps/model.rb +386 -0
  17. data/features/steps/rod.rb +71 -0
  18. data/features/steps/test_helper.rb +5 -0
  19. data/lib/rod/abstract_database.rb +17 -5
  20. data/lib/rod/constants.rb +1 -1
  21. data/lib/rod/database.rb +95 -74
  22. data/lib/rod/join_element.rb +6 -2
  23. data/lib/rod/model.rb +37 -9
  24. data/rod.gemspec +15 -12
  25. data/tests/check_strings.rb +10 -0
  26. data/tests/class_compatibility_create.rb +14 -0
  27. data/tests/class_compatibility_verify.rb +18 -0
  28. data/tests/eff1_test.rb +60 -0
  29. data/tests/eff2_test.rb +61 -0
  30. data/tests/full_runs.rb +68 -0
  31. data/tests/generate_classes_create.rb +25 -0
  32. data/tests/generate_classes_model.rb +23 -0
  33. data/tests/generate_classes_rewrite.rb +7 -0
  34. data/tests/generate_classes_verify.rb +46 -0
  35. data/tests/load_struct.rb +24 -0
  36. data/tests/migration_create.rb +25 -0
  37. data/tests/migration_migrate.rb +22 -0
  38. data/tests/migration_model1.rb +23 -0
  39. data/tests/migration_model2.rb +27 -0
  40. data/tests/migration_verify.rb +56 -0
  41. data/tests/mock_tests.rb +128 -0
  42. data/tests/read_on_create.rb +45 -0
  43. data/tests/save_struct.rb +49 -0
  44. data/tests/structures.rb +52 -0
  45. data/tests/unit/database.rb +60 -0
  46. data/tests/unit/model.rb +36 -0
  47. data/tests/unit/model_tests.rb +116 -0
  48. data/tests/validate_read_on_create.rb +12 -0
  49. data/utils/convert_index.rb +31 -0
  50. metadata +77 -28
@@ -0,0 +1,113 @@
1
+ Feature: Store and load data from multiple databases
2
+
3
+ Background:
4
+ Given the library works in development mode
5
+
6
+ Scenario: two classes with two dbs
7
+ Given the class space is cleared
8
+ And a class Caveman inherits from Rod::Model
9
+ And a class Caveman has a name field of type string
10
+ And a class Caveman is connected to Database1
11
+ And a class Automobile inherits from Rod::Model
12
+ And a class Automobile has a name field of type string
13
+ And a class Automobile is connected to Database2
14
+ When Database1 is created
15
+ And Database2 is created
16
+ And I create a Caveman
17
+ And his name is 'Fred'
18
+ And I store him in the database
19
+ And I create an Automobile
20
+ And its name is 'Prehistoric'
21
+ And I store him in the database
22
+ And I reopen Database1 for reading
23
+ And I reopen Database2 for reading
24
+ Then there should be 1 Caveman
25
+ And the name of the first Caveman should be 'Fred'
26
+ And there should be 1 Automobile
27
+ And the name of the first Automobile should be 'Prehistoric'
28
+
29
+ Scenario: three classes with two dbs and consistent hierarchy
30
+ A connected to DB1
31
+ B < A connected to DB2
32
+ C < B connected to DB2
33
+
34
+ Given the class space is cleared
35
+ And a class Person inherits from Rod::Model
36
+ And a class Person has a name field of type string
37
+ And a class Person is connected to Database1
38
+ And a class User inherits from Person
39
+ And a class User has a login field of type string
40
+ And a class User is connected to Database2
41
+ And a class SuperUser inherits from User
42
+ And a class SuperUser has a room field of type string
43
+ When Database1 is created
44
+ And Database2 is created
45
+ And I create a Person
46
+ And his name is 'John'
47
+ And I store him in the database
48
+ And I create a User
49
+ And her name is 'Annie'
50
+ And her login is 'ann123'
51
+ And I store her in the database
52
+ And I create a SuperUser
53
+ And his name is 'Nerd'
54
+ And his login is 'n4rrd'
55
+ And his room is '2-111'
56
+ And I store him in the database
57
+ And I reopen Database1 for reading
58
+ And I reopen Database2 for reading
59
+ Then there should be 1 Person(s)
60
+ And there should be 1 User(s)
61
+ And there should be 1 SuperUser
62
+ And the name of the first Person should be 'John'
63
+ And the first Person should not have a login field
64
+ And the first Person should not have a room field
65
+ And the name of the first User should be 'Annie'
66
+ And the login of the first User should be 'ann123'
67
+ And the first User should not have a room field
68
+ And the name of the first SuperUser should be 'Nerd'
69
+ And the login of the first SuperUser should be 'n4rrd'
70
+ And the room of the first SuperUser should be '2-111'
71
+
72
+ Scenario: three classes with two dbs and consistent hierarchy:
73
+ A connected to DB1
74
+ B < A connected to DB2
75
+ C < B connected to DB1
76
+
77
+ Given the class space is cleared
78
+ And a class Person inherits from Rod::Model
79
+ And a class Person has a name field of type string
80
+ And a class Person is connected to Database1
81
+ And a class User inherits from Person
82
+ And a class User has a login field of type string
83
+ And a class SuperUser inherits from User
84
+ And a class SuperUser has a room field of type string
85
+ And a class User is connected to Database2
86
+ When Database1 is created
87
+ And Database2 is created
88
+ And I create a Person
89
+ And his name is 'John'
90
+ And I store him in the database
91
+ And I create a User
92
+ And her name is 'Annie'
93
+ And her login is 'ann123'
94
+ And I store her in the database
95
+ And I create a SuperUser
96
+ And his name is 'Nerd'
97
+ And his login is 'n4rrd'
98
+ And his room is '2-111'
99
+ And I store him in the database
100
+ And I reopen Database1 for reading
101
+ And I reopen Database2 for reading
102
+ Then there should be 1 Person(s)
103
+ And there should be 1 User(s)
104
+ And there should be 1 SuperUser
105
+ And the name of the first Person should be 'John'
106
+ And the first Person should not have a login field
107
+ And the first Person should not have a room field
108
+ And the name of the first User should be 'Annie'
109
+ And the login of the first User should be 'ann123'
110
+ And the first User should not have a room field
111
+ And the name of the first SuperUser should be 'Nerd'
112
+ And the login of the first SuperUser should be 'n4rrd'
113
+ And the room of the first SuperUser should be '2-111'
@@ -0,0 +1,195 @@
1
+ Feature: relationships between different classes
2
+ In order to ensure relationship storage, ROD should
3
+ allow to store and load data having connections with other data
4
+ Background:
5
+ Given the library works in development mode
6
+
7
+ Scenario: two classes with has one relationship
8
+ Given the class space is cleared
9
+ And the model is connected with the default database
10
+ And a class Caveman has a name field of type string
11
+ And a class Automobile has a name field of type string
12
+ And a class Caveman has one automobile
13
+ When the database is created
14
+ And I create an Automobile
15
+ And its name is 'Prehistoric car'
16
+ And I store it in the database
17
+ And I create a Caveman
18
+ And his name is 'Fred'
19
+ And his automobile is the first Automobile created
20
+ And I store him in the database
21
+ And I reopen database for reading
22
+ Then there should be 1 Caveman
23
+ And there should be 1 Automobile
24
+ And the name of the first Caveman should be 'Fred'
25
+ And the name of the first Automobile should be 'Prehistoric car'
26
+ And the automobile of the first Caveman should be equal to the first Automobile
27
+
28
+ # Should store nil
29
+ When the database is created
30
+ And I create a Caveman
31
+ And his name is 'Willma'
32
+ And his automobile is nil
33
+ And I store him in the database
34
+ And I reopen database for reading
35
+ Then there should be 1 Caveman
36
+ And the name of the first Caveman should be 'Willma'
37
+ And the automobile of the first Caveman should be nil
38
+
39
+ Scenario: two classes with has many relationship
40
+ Given the class space is cleared
41
+ And the model is connected with the default database
42
+ And a class Caveman has a name field of type string
43
+ And a class Automobile has a name field of type string
44
+ And a class Caveman has many automobiles
45
+ When the database is created
46
+ And I create an Automobile
47
+ And its name is 'Prehistoric car'
48
+ And I store it in the database
49
+ And I create another Automobile
50
+ And its name is 'Modern car'
51
+ And I store it in the database
52
+ And I create a Caveman
53
+ And his name is 'Fred'
54
+ And his automobiles contain the first Automobile created
55
+ And his automobiles contain the second Automobile created
56
+ And I store him in the database
57
+ And I reopen database for reading
58
+ Then there should be 1 Caveman
59
+ And there should be 2 Automobile(s)
60
+ And the name of the first Caveman should be 'Fred'
61
+ And the name of the first Automobile should be 'Prehistoric car'
62
+ And the name of the second Automobile should be 'Modern car'
63
+ And the first Caveman should have 2 automobiles
64
+ And the first of automobiles of the first Caveman should be equal to the first Automobile
65
+ And the second of automobiles of the first Caveman should be equal to the second Automobile
66
+
67
+ # Should store in any order
68
+ When the database is created
69
+ And I create an Automobile
70
+ And its name is 'Prehistoric car'
71
+ And I create another Automobile
72
+ And its name is 'Modern car'
73
+ And I create a Caveman
74
+ And his name is 'Fred'
75
+ And his automobiles contain the first Automobile created
76
+ And his automobiles contain the second Automobile created
77
+ And I store the first Caveman in the database
78
+ And I store the first Automobile in the database
79
+ And I store the second Automobile in the database
80
+ And I reopen database for reading
81
+ Then there should be 1 Caveman
82
+ And there should be 2 Automobile(s)
83
+ And the first Caveman should have 2 automobiles
84
+
85
+ # Should store nil
86
+ When the database is created
87
+ And I create an Automobile
88
+ And its name is 'Prehistoric car'
89
+ And I create another Automobile
90
+ And its name is 'Modern car'
91
+ And I create a Caveman
92
+ And his name is 'Fred'
93
+ And his automobiles contain the first Automobile created
94
+ And his automobiles contain nil
95
+ And his automobiles contain the second Automobile created
96
+ And I store the first Caveman in the database
97
+ And I store the first Automobile in the database
98
+ And I store the second Automobile in the database
99
+ And I reopen database for reading
100
+ Then there should be 1 Caveman
101
+ And there should be 2 Automobile(s)
102
+ And the first Caveman should have 3 automobiles
103
+ And the first of automobiles of the first Caveman should be equal to the first Automobile
104
+ And the second of automobiles of the first Caveman should be nil
105
+ And the third of automobiles of the first Caveman should be equal to the second Automobile
106
+
107
+ Scenario: three classes with has one polymorphic association
108
+ Given the class space is cleared
109
+ And the model is connected with the default database
110
+ And a class Caveman has a name field of type string
111
+ And a class Caveman has one polymorphic item
112
+ And a class Automobile has a name field of type string
113
+ And a class Dog has a nickname field of type string
114
+ When the database is created
115
+ And I create an Automobile
116
+ And its name is 'Prehistoric car'
117
+ And I store it in the database
118
+ And I create a Dog
119
+ And its nickname is 'Snoopy'
120
+ And I store it in the database
121
+ And I create a Caveman
122
+ And his name is 'Fred'
123
+ And his item is the first Automobile created
124
+ And I store him in the database
125
+ And I create another Caveman
126
+ And her name is 'Willma'
127
+ And her item is the first Dog created
128
+ And I store her in the database
129
+ And I reopen database for reading
130
+ Then there should be 2 Caveman(s)
131
+ And there should be 1 Automobile
132
+ And there should be 1 Dog
133
+ And the item of the first Caveman should be equal to the first Automobile
134
+ And the item of the second Caveman should be equal to the first Dog
135
+
136
+ # should store nil
137
+ When the database is created
138
+ And I create a Caveman
139
+ And his name is 'Willma'
140
+ And his item is nil
141
+ And I store him in the database
142
+ And I reopen database for reading
143
+ Then there should be 1 Caveman
144
+ And the name of the first Caveman should be 'Willma'
145
+ And the item of the first Caveman should be nil
146
+
147
+ Scenario: three classes with has many polymorphic association
148
+ Given the class space is cleared
149
+ And the model is connected with the default database
150
+ And a class Caveman has a name field of type string
151
+ And a class Caveman has many polymorphic items
152
+ And a class Automobile has a name field of type string
153
+ And a class Dog has a nickname field of type string
154
+ When the database is created
155
+ And I create an Automobile
156
+ And its name is 'Prehistoric car'
157
+ And I store it in the database
158
+ And I create a Dog
159
+ And its nickname is 'Snoopy'
160
+ And I store it in the database
161
+ And I create a Caveman
162
+ And his name is 'Fred'
163
+ And his items contain the first Automobile created
164
+ And his items contain the first Dog created
165
+ And I store him in the database
166
+ And I reopen database for reading
167
+ Then there should be 1 Caveman
168
+ And there should be 1 Automobile
169
+ And there should be 1 Dog
170
+ And the first Caveman should have 2 items
171
+ And the first of items of the first Caveman should be equal to the first Automobile
172
+ And the second of items of the first Caveman should be equal to the first Dog
173
+
174
+ # should store nil
175
+ When the database is created
176
+ And I create an Automobile
177
+ And its name is 'Prehistoric car'
178
+ And I store it in the database
179
+ And I create a Dog
180
+ And its nickname is 'Snoopy'
181
+ And I store it in the database
182
+ And I create a Caveman
183
+ And his name is 'Fred'
184
+ And his items contain the first Automobile created
185
+ And his items contain nil
186
+ And his items contain the first Dog created
187
+ And I store him in the database
188
+ And I reopen database for reading
189
+ Then there should be 1 Caveman
190
+ And there should be 1 Automobile
191
+ And there should be 1 Dog
192
+ And the first Caveman should have 3 items
193
+ And the first of items of the first Caveman should be equal to the first Automobile
194
+ And the second of items of the first Caveman should be nil
195
+ And the third of items of the first Caveman should be equal to the first Dog
@@ -0,0 +1,172 @@
1
+ Feature: Access to objects with segmented indices.
2
+ ROD allows for accessing objects via fields with segmented indices,
3
+ which are useful for indices with millions of keys.
4
+ These are split accross multiple files for faster load-time.
5
+ Background:
6
+ Given the library works in development mode
7
+
8
+ Scenario: indexing with segmented index
9
+ Rod should allow to access objects via values of their fields,
10
+ for which indices were built.
11
+ Given the class space is cleared
12
+ And the model is connected with the default database
13
+ And a class Caveman has a name field of type string with segmented index
14
+ And a class Caveman has an age field of type integer with segmented index
15
+ And a class Caveman has an identifier field of type ulong with segmented index
16
+ And a class Caveman has a height field of type float with segmented index
17
+ When database is created
18
+ And I create a Caveman
19
+ And his name is 'Fred'
20
+ And his age is '25'
21
+ And his identifier is '111122223333'
22
+ And his height is '1.86'
23
+ And I store him in the database
24
+ And I create another Caveman
25
+ And his name is 'Barney'
26
+ And his age is '26'
27
+ And his identifier is '111122224444'
28
+ And his height is '1.67'
29
+ And I store him in the database
30
+ And I create another Caveman
31
+ And his name is 'Wilma'
32
+ And his age is '25'
33
+ And his identifier is '111122225555'
34
+ And his height is '1.67'
35
+ And I store her in the database
36
+ And I reopen database for reading
37
+ Then there should be 3 Caveman(s)
38
+ And there should be 1 Caveman with 'Fred' name
39
+ And there should be 1 Caveman with 'Wilma' name
40
+ And there should be 1 Caveman with 'Barney' name
41
+ And there should be 2 Caveman(s) with '25' age
42
+ And there should be 1 Caveman with '26' age
43
+ And there should be 1 Caveman with '111122223333' identifier
44
+ And there should be 1 Caveman with '111122224444' identifier
45
+ And there should be 1 Caveman with '111122225555' identifier
46
+ And there should be 2 Caveman(s) with '1.67' height
47
+ And there should be 1 Caveman with '1.86' height
48
+
49
+ # Test re-creation of the database
50
+ When database is created
51
+ And I create a Caveman
52
+ And his name is 'Fred'
53
+ And I store him in the database
54
+ And I create another Caveman
55
+ And his name is 'Barney'
56
+ And I store him in the database
57
+ And I create another Caveman
58
+ And her name is 'Wilma'
59
+ And I store her in the database
60
+ And I reopen database for reading
61
+ Then there should be 3 Caveman(s)
62
+ And there should be 1 Caveman with 'Fred' name
63
+ And there should be 1 Caveman with 'Wilma' name
64
+ And there should be 1 Caveman with 'Barney' name
65
+
66
+ Scenario: extending the DB when segmented index is used
67
+ Rod should allow to extend the DB when the segmented index is used.
68
+ The index should be properly updated.
69
+ Given the class space is cleared
70
+ And the model is connected with the default database
71
+ And a class Caveman has a name field of type string with segmented index
72
+ When database is created
73
+ And I create a Caveman
74
+ And his name is 'Fred'
75
+ And I store him in the database
76
+ And I create another Caveman
77
+ And his name is 'Barney'
78
+ And I store him in the database
79
+ And I reopen database
80
+ And I create another Caveman
81
+ And her name is 'Wilma'
82
+ And I store her in the database
83
+ And I create another Caveman
84
+ And his name is 'Fred'
85
+ And I store him in the database
86
+ And I reopen database for reading
87
+ Then there should be 4 Caveman(s)
88
+ And there should be 1 Caveman with 'Wilma' name
89
+ And there should be 2 Caveman(s) with 'Fred' name
90
+ And there should be 1 Caveman with 'Barney' name
91
+
92
+ Scenario: indexing of fields with different DBs for the same model with segmented index
93
+ The contents of indices should be fulshed when the database is reopened.
94
+ Given the class space is cleared
95
+ And the model is connected with the default database
96
+ And a class Caveman has a name field of type string with segmented index
97
+ When database is created
98
+ And I create a Caveman
99
+ And his name is 'Fred'
100
+ And I store him in the database
101
+ And I create another Caveman
102
+ And his name is 'Fred'
103
+ And I store him in the database
104
+ And I create another Caveman
105
+ And his name is 'Fred'
106
+ And I store him in the database
107
+ And I reopen database for reading
108
+ And I access the Caveman name index
109
+ And database is created in location2
110
+ And I create a Caveman
111
+ And his name is 'Wilma'
112
+ And I store him in the database
113
+ And I create another Caveman
114
+ And his name is 'Wilma'
115
+ And I store him in the database
116
+ And I create another Caveman
117
+ And his name is 'Wilma'
118
+ And I store him in the database
119
+ And I reopen database for reading in location2
120
+ Then there should be 3 Caveman(s)
121
+ And there should be 3 Caveman(s) with 'Wilma' name
122
+ And there should be 0 Caveman(s) with 'Fred' name
123
+
124
+ Scenario: indexing of particular values with segmented index
125
+ Given the class space is cleared
126
+ And the model is connected with the default database
127
+ And a class Caveman has a name field of type string with segmented index
128
+ And a class Caveman has a surname field of type string with segmented index
129
+ And a class Caveman has a login field of type string with segmented index
130
+ And a class Caveman has an age field of type integer with segmented index
131
+ When database is created
132
+ And I create and store the following Caveman(s):
133
+ | name | surname | login | age |
134
+ | John | Smith | john | 12 |
135
+ | Lara | Croft | lara | 23 |
136
+ | Adam | Parker | adam | 12 |
137
+ | Adam | | noob1 | 33 |
138
+ | | | noob2 | -1 |
139
+ | | Adam | noob1 | 33 |
140
+ And I reopen database for reading
141
+ Then there should be 6 Caveman(s)
142
+ And there should be 1 Caveman with 'John' name
143
+ And there should be 2 Caveman(s) with 'Adam' name
144
+ And there should be 2 Caveman(s) with '12' age
145
+ And there should be 1 Caveman with '-1' age
146
+ And there should be 2 Caveman(s) with '' name
147
+ And there should be 2 Caveman(s) with '' surname
148
+
149
+ Scenario: multiple object with indexed fields with segmented index
150
+ The database should properly store thausands of objects with some indexed fields.
151
+ Given the class space is cleared
152
+ And the model is connected with the default database
153
+ And a class User has a name field of type string with segmented index
154
+ And a class User has a surname field of type string with segmented index
155
+ And a class User has an age field of type integer
156
+ When database is created
157
+ And I create a User
158
+ And his name is 'John'
159
+ And his surname is 'Smith'
160
+ And his age is '21'
161
+ And I store him in the database 1000 times
162
+ And I create a User
163
+ And her name is 'Lara'
164
+ And her surname is 'Croft'
165
+ And her age is '23'
166
+ And I store her in the database 1000 times
167
+ And I reopen database for reading
168
+ Then there should be 2000 User(s)
169
+ Then there should be 1000 User(s) with 'John' name
170
+ Then there should be 1000 User(s) with 'Smith' surname
171
+ Then there should be 1000 User(s) with 'Lara' name
172
+ Then there should be 1000 User(s) with 'Croft' surname