rod 0.6.1 → 0.6.2

Sign up to get free protection for your applications and to get access to all the features.
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