git-ds 0.9.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 (51) hide show
  1. data/README.rdoc +795 -0
  2. data/doc/Examples.rdoc +36 -0
  3. data/doc/examples/key_value/kv_get.rb +29 -0
  4. data/doc/examples/key_value/kv_init.rb +20 -0
  5. data/doc/examples/key_value/kv_list.rb +28 -0
  6. data/doc/examples/key_value/kv_remove.rb +29 -0
  7. data/doc/examples/key_value/kv_set.rb +39 -0
  8. data/doc/examples/key_value/model.rb +156 -0
  9. data/doc/examples/key_value/test.rb +50 -0
  10. data/doc/examples/test_suite/model.rb +503 -0
  11. data/doc/examples/test_suite/test.rb +173 -0
  12. data/doc/examples/test_suite/ts_add_bug.rb +65 -0
  13. data/doc/examples/test_suite/ts_add_module.rb +74 -0
  14. data/doc/examples/test_suite/ts_add_module_to_test.rb +78 -0
  15. data/doc/examples/test_suite/ts_add_test.rb +77 -0
  16. data/doc/examples/test_suite/ts_add_test_suite.rb +65 -0
  17. data/doc/examples/test_suite/ts_add_test_to_bug.rb +76 -0
  18. data/doc/examples/test_suite/ts_init.rb +20 -0
  19. data/doc/examples/test_suite/ts_list.rb +118 -0
  20. data/doc/examples/test_suite/ts_perform_test.rb +104 -0
  21. data/doc/examples/test_suite/ts_update_bugs.rb +58 -0
  22. data/doc/examples/user_group/model.rb +265 -0
  23. data/doc/examples/user_group/test.rb +64 -0
  24. data/doc/examples/user_group/ug_add_group.rb +39 -0
  25. data/doc/examples/user_group/ug_add_group_user.rb +36 -0
  26. data/doc/examples/user_group/ug_add_user.rb +39 -0
  27. data/doc/examples/user_group/ug_init.rb +20 -0
  28. data/doc/examples/user_group/ug_list.rb +32 -0
  29. data/lib/git-ds.rb +14 -0
  30. data/lib/git-ds/config.rb +53 -0
  31. data/lib/git-ds/database.rb +289 -0
  32. data/lib/git-ds/exec_cmd.rb +107 -0
  33. data/lib/git-ds/index.rb +205 -0
  34. data/lib/git-ds/model.rb +136 -0
  35. data/lib/git-ds/model/db_item.rb +42 -0
  36. data/lib/git-ds/model/fs_item.rb +51 -0
  37. data/lib/git-ds/model/item.rb +428 -0
  38. data/lib/git-ds/model/item_list.rb +97 -0
  39. data/lib/git-ds/model/item_proxy.rb +128 -0
  40. data/lib/git-ds/model/property.rb +144 -0
  41. data/lib/git-ds/model/root.rb +46 -0
  42. data/lib/git-ds/repo.rb +455 -0
  43. data/lib/git-ds/shared.rb +17 -0
  44. data/lib/git-ds/transaction.rb +77 -0
  45. data/tests/ut_database.rb +304 -0
  46. data/tests/ut_git_grit_equiv.rb +195 -0
  47. data/tests/ut_index.rb +203 -0
  48. data/tests/ut_model.rb +360 -0
  49. data/tests/ut_repo.rb +260 -0
  50. data/tests/ut_user_group_model.rb +316 -0
  51. metadata +142 -0
data/tests/ut_repo.rb ADDED
@@ -0,0 +1,260 @@
1
+ #!/usr/bin/env ruby
2
+ # Copyright 2010 Thoughtgang <http://www.thoughtgang.org>
3
+ # Unit test for Git-DS Repo class
4
+
5
+ require 'test/unit'
6
+ require 'fileutils'
7
+
8
+ require 'git-ds/repo'
9
+
10
+ class TC_GitRepoTest < Test::Unit::TestCase
11
+ TMP = File.dirname(__FILE__) + File::SEPARATOR + 'tmp'
12
+
13
+ attr_reader :repo
14
+
15
+ def setup
16
+ FileUtils.remove_dir(TMP) if File.exist?(TMP)
17
+ Dir.mkdir(TMP)
18
+
19
+ path = TMP + File::SEPARATOR + 'test'
20
+ @repo = GitDS::Repo.create(path)
21
+
22
+ # add basic structure to repo
23
+ idx = @repo.index
24
+ idx.add( 'class a/instance a/prop a', 'aaaaaaaaaa' )
25
+ idx.add( 'class a/instance a/prop b', 'bbbbbbbbbb' )
26
+ idx.add( 'class a/instance b/prop a', 'AAAAAAAAAA' )
27
+ idx.add( 'class a/instance b/prop b', 'BBBBBBBBBB' )
28
+ idx.add( 'class b/instance a/prop a', '1111111111' )
29
+ idx.add( 'class b/instance a/prop b', '2222222222' )
30
+ idx.add( 'class c/instance a/prop a', 'zzzzzzzzzz' )
31
+ idx.add( 'class c/instance a/prop b', 'xxxxxxxxxx' )
32
+ idx.add( 'class c/instance a/class d/prop 1', '-_-_-_-_-_' )
33
+ idx.add( 'class c/instance a/class d/prop 2', '=+=+=+=+=+' )
34
+
35
+ idx.commit('initial import')
36
+ @repo.staging = nil
37
+ end
38
+
39
+ def teardown
40
+ FileUtils.remove_dir(TMP) if File.exist?(TMP)
41
+ end
42
+
43
+ def test_create
44
+ path = TMP + File::SEPARATOR + 'test_create'
45
+ repo = GitDS::Repo.create(path)
46
+
47
+ assert(File.exist?(path + File::SEPARATOR + '.git'),
48
+ "Repo #{path} not created!")
49
+ assert_equal(path, repo.top_level, 'Repo#top_level returned wrong value')
50
+
51
+ repo.exec_in_git_dir {
52
+ assert( File.exist?('.git'), 'Repo#exec_in_git_dir failed' )
53
+ }
54
+ # TODO: repo.exec_git_cmd()
55
+ end
56
+
57
+ def test_list
58
+ dir = 'class c/instance a/class d'
59
+ path, data = "#{dir}/prop 1", '-_-_-_-_-_'
60
+
61
+ # test include
62
+ assert( @repo.include?(dir), 'Repo#include? does not include path' )
63
+ assert( @repo.include?(path), 'Repo#include? does not include path' )
64
+
65
+ assert_nil( @repo.object_data(dir), 'blob data returned for path' )
66
+ assert_equal( data, @repo.path_to_object(path).data,
67
+ 'Repo#path_to_object#data returned wrong data for blob' )
68
+ assert_equal( data, @repo.object_data(path),
69
+ 'Repo#object_data returned wrong data for blob' )
70
+
71
+ # Test listing of tree contents
72
+ assert_equal( 3, @repo.tree_contents(@repo.tree).keys.count,
73
+ 'Repo#list returns wrong contents for root tree' )
74
+ assert_equal( 3, @repo.tree_contents(@repo.tree(@repo.root_sha)).keys.count,
75
+ 'Repo#list returns wrong contents for root_sha' )
76
+ assert_equal( ['class a', 'class b', 'class c'], @repo.list.keys.sort,
77
+ 'Repo#list returns wrong contents for root' )
78
+ assert_equal( ['instance a', 'instance b'], @repo.list('class a').keys.sort,
79
+ 'Repo#list returns wrong contents for "class a"' )
80
+
81
+ # Test listing of only Blobs or only Trees
82
+ assert_equal(0, @repo.list_blobs().count, 'List Blobs has wrong root count')
83
+ assert_equal(3, @repo.list_trees().count, 'List Trees has wrong root count')
84
+ assert_equal(2, @repo.list_blobs('class c/instance a').count,
85
+ 'List Blobs has wrong count')
86
+ assert_equal(1, @repo.list_trees('class c/instance a').count,
87
+ 'List Trees has wrong count')
88
+
89
+ # Test recursive raw-tree generation
90
+ output = @repo.raw_tree('class c')
91
+ assert_equal(1, output.split("\n").count, 'Incorrect count for raw_tree')
92
+ output = @repo.raw_tree('class c', true)
93
+ assert_equal(4, output.split("\n").count, 'Incorrect count for raw_tree')
94
+
95
+ # Make sure that '' gets us a root Tree object
96
+ output = @repo.raw_tree('')
97
+ assert_equal(3, output.split("\n").count, 'Incorrect count for raw_tree')
98
+ output = @repo.raw_tree('', true)
99
+ assert_equal(10, output.split("\n").count, 'Incorrect count for raw_tree')
100
+ end
101
+
102
+ def test_index
103
+ idx = @repo.index_new
104
+ assert_equal(GitDS::Index, idx.class, 'Repo#index_new returns wrong class')
105
+ idx = @repo.index
106
+ assert_equal(GitDS::StageIndex, idx.class, 'Repo#index returns wrong class')
107
+
108
+ assert( @repo.staging?(), 'Repo#staging returned FALSE' )
109
+
110
+ path, data = 'class c/instance a/prop b', 'XXXXXXXXXX'
111
+ @repo.stage { |idx|
112
+ idx.add( path, data )
113
+ }
114
+
115
+ assert_equal(data, @repo.object_data(path), 'Stage did not write data')
116
+
117
+ @repo.staging = nil
118
+ assert( (not @repo.staging?), 'Repo#staging returned TRUE' )
119
+
120
+ msg = 'this is a test'
121
+ @repo.stage_and_commit(msg) { |idx|
122
+ idx.add( path, data )
123
+ }
124
+
125
+ # ensure this doesn't screw up repo
126
+ output = @repo.raw_tree('')
127
+ assert_equal(3, output.split("\n").count, 'Incorrect count for raw_tree')
128
+ end
129
+
130
+ def test_branch_and_tag
131
+ assert_equal(0, @repo.tags.count, 'Expected initial tag count of 0')
132
+ assert_equal('1_2_3_4_5_6_7_8_9_0_',
133
+ @repo.clean_tag('1!2@3#4$5%6^7&8*9(0)'),
134
+ 'clean_tag did not clean')
135
+
136
+ # Tag a commit
137
+ sha = @repo.commits.first.id
138
+ name = 'the tag is'
139
+ @repo.tag_object(name, sha)
140
+ assert_equal(1, @repo.tags.count, 'Tag did not get added')
141
+ assert_equal('the_tag_is', @repo.tags.first.name, 'Tag name did not match')
142
+ assert_equal(1,
143
+ @repo.tags.select{|t| t.name == @repo.clean_tag(name)}.count,
144
+ 'Tag did not get added with right name')
145
+
146
+ assert_equal('0.0.0', @repo.last_branch_tag, 'invalid initial tag value')
147
+ assert_equal('0.0.1', @repo.next_branch_tag, 'next_branch_tag failed')
148
+
149
+ assert_equal(GitDS::Repo::DEFAULT_BRANCH, @repo.current_branch,
150
+ 'Current branch is not default branch')
151
+ assert_equal(GitDS::Repo::DEFAULT_BRANCH, @repo.branch.name,
152
+ 'Current branch is not default branch')
153
+
154
+ # create new branch
155
+ assert_equal(1, @repo.branches.count, '> 1 branches exist on init')
156
+ new_branch = @repo.create_branch( 'v01' )
157
+ assert_equal(2, @repo.branches.count, 'new branch not added')
158
+
159
+ # switch to new branch
160
+ @repo.set_branch(new_branch)
161
+ assert_equal(new_branch, @repo.current_branch, 'Curr branch != new branch')
162
+ assert_equal(new_branch, @repo.branch.name, 'Current branch != new branch')
163
+
164
+ # switch back
165
+ @repo.set_branch(GitDS::Repo::DEFAULT_BRANCH)
166
+ assert_equal(GitDS::Repo::DEFAULT_BRANCH, @repo.branch.name,
167
+ 'Current branch is not default branch')
168
+
169
+ # create new branch with auto-tag name of 0.0.2
170
+ v2 = @repo.create_branch
171
+ assert_equal('0.0.2', v2, 'New branch did not get assigned 0.0.2 name')
172
+ assert_equal(3, @repo.branches.count, 'new branch not added')
173
+
174
+ # switch to new branch and change data
175
+ @repo.set_branch(new_branch)
176
+ path, data = 'class c/instance a/prop b', '~~~~~~~~~~'
177
+ @repo.stage_and_commit('test commit for merge') { |idx|
178
+ idx.add( path, data )
179
+ }
180
+ assert_equal(data, @repo.object_data(path), 'Stage did not write data')
181
+
182
+ # test that staging index gets preserved
183
+ b_stage = @repo.staging
184
+ @repo.set_branch(GitDS::Repo::DEFAULT_BRANCH)
185
+ assert( (not @repo.staging?), 'Staging index not cleared on branch' )
186
+ @repo.set_branch(new_branch)
187
+ assert( (@repo.staging?), 'Staging index not restored on branch' )
188
+ assert_equal(b_stage, @repo.staging, 'Staging index not saved on branch')
189
+
190
+ # merge new branch to master
191
+ @repo.merge_branch
192
+ assert_equal(GitDS::Repo::DEFAULT_BRANCH, @repo.branch.name,
193
+ 'Current branch is not default branch')
194
+ assert_equal(data, @repo.object_data(path), 'Merge did not write data')
195
+ end
196
+
197
+ def test_index_mod_and_list
198
+ path, data = 'class e/prop_1', '.:.:.:.:.'
199
+
200
+ # list top-level should have 3 entries
201
+ assert_equal( 3, @repo.tree_contents(@repo.tree).keys.count,
202
+ 'Repo#list returns wrong contents for root tree' )
203
+
204
+ @repo.add( path, data )
205
+ assert_equal( data, @repo.object_data(path),
206
+ 'Repo#object_data returned wrong data for blob' )
207
+
208
+ # list top-level should have 4 entries
209
+ assert_equal( 4, @repo.tree_contents(@repo.tree).keys.count,
210
+ 'Repo#list returns wrong contents for root tree' )
211
+
212
+ # Discard staging index
213
+ @repo.unstage
214
+
215
+ # list top-level should have 3 entries again
216
+ assert_equal( 3, @repo.tree_contents(@repo.tree).keys.count,
217
+ 'Repo#list returns wrong contents for root tree' )
218
+
219
+ @repo.add( path, data )
220
+ assert_equal( data, @repo.object_data(path),
221
+ 'Repo#object_data returned wrong data for blob' )
222
+
223
+ @repo.delete('class e/')
224
+
225
+ # list top-level should have 3 entries again
226
+ assert_equal( 3, @repo.tree_contents(@repo.tree).keys.count,
227
+ 'Repo#list returns wrong contents for root tree' )
228
+ @repo.staging=nil
229
+
230
+ # TODO: modification while index is active.
231
+ end
232
+
233
+ def test_add_fs
234
+ path, data = 'test-fs', 'trtrtrtrt'
235
+ @repo.add(path, data, true)
236
+ assert_equal( 4, @repo.tree_contents(@repo.tree).keys.count,
237
+ 'Repo#list returns wrong contents for root tree' )
238
+
239
+ @repo.exec_in_git_dir {
240
+ assert( ::File.exist?(path), 'File not exist after repo-fs-add' )
241
+ }
242
+
243
+ @repo.unstage
244
+ end
245
+
246
+ def test_add_db
247
+ path, data = 'test-db', 'bdbdbdbdb'
248
+ @repo.add(path, data)
249
+ assert_equal( 4, @repo.tree_contents(@repo.tree).keys.count,
250
+ 'Repo#list returns wrong contents for root tree' )
251
+
252
+ @repo.exec_in_git_dir {
253
+ assert( (not ::File.exist? path), 'File exists after repo-db-add' )
254
+ }
255
+
256
+ @repo.unstage
257
+ end
258
+
259
+ end
260
+
@@ -0,0 +1,316 @@
1
+ #!/usr/bin/env ruby
2
+ # Copyright 2011 Thoughtgang <http://www.thoughtgang.org>
3
+ # Unit test for Git-DS Model class API
4
+
5
+ require 'test/unit'
6
+ require 'fileutils'
7
+
8
+ require 'git-ds/database'
9
+ require 'git-ds/model'
10
+
11
+ # =============================================================================
12
+ # Test database model:
13
+ # user/ : FsModelItemClass
14
+ # user/$NAME/ : FsModelItem
15
+ # user/$NAME/id : Property
16
+ # user/$NAME/role/ : DbModelItemClass
17
+ # user/$NAME/role/$NAME/ : DbModelItem
18
+ # user/$NAME/role/$NAME/auth : Property
19
+ #
20
+ # group/ : FsModelItemClass
21
+ # group/$NAME/ : FsModelItem
22
+ # group/$NAME/id : Property
23
+
24
+ # ----------------------------------------------------------------------
25
+ # User Role. This is an in-DB item.
26
+ class UserRoleModelItem
27
+ include GitDS::DbModelItemObject
28
+ extend GitDS::DbModelItemClass
29
+
30
+ name 'role'
31
+
32
+ property(:auth, 127) { |p| p.to_s.to_i == p && p >= 0 && p < 1024 }
33
+
34
+ def auth
35
+ integer_property(:auth)
36
+ end
37
+
38
+ def auth=(val)
39
+ set_property(:auth, val)
40
+ end
41
+ end
42
+
43
+ # ----------------------------------------------------------------------
44
+ class UserModelItem
45
+ include GitDS::FsModelItemObject
46
+ extend GitDS::FsModelItemClass
47
+
48
+ name 'user'
49
+
50
+ # properties
51
+ property(:id, 0) { |p| p.to_s.to_i == p }
52
+
53
+ def initialize(model, path)
54
+ super
55
+ @roles = GitDS::ModelItemList.new(UserRoleModelItem, model, path)
56
+ end
57
+
58
+ # Use :username entry in Hash as primary key
59
+ def self.ident_key
60
+ :username
61
+ end
62
+
63
+ # Override default fill method to set non-Property children
64
+ def self.fill(model, item_path, args)
65
+ super
66
+
67
+ # create user role
68
+ args[:roles].each do |role|
69
+ UserRoleModelItem.create_in_path(model, item_path, role)
70
+ end
71
+ end
72
+
73
+ alias :username :ident
74
+
75
+ def id
76
+ integer_property(:id)
77
+ end
78
+
79
+ def id=(val)
80
+ set_property(:id, val)
81
+ end
82
+
83
+ def roles
84
+ ensure_valid
85
+ @roles.keys
86
+ end
87
+
88
+ def role(name)
89
+ ensure_valid
90
+ @roles[name]
91
+ end
92
+
93
+ def add_role(ident, auth)
94
+ @roles.add(self, {:ident => ident, :auth => auth})
95
+ end
96
+
97
+ end
98
+
99
+ # ----------------------------------------------------------------------
100
+ class GroupModelItem
101
+ include GitDS::FsModelItemObject
102
+ extend GitDS::FsModelItemClass
103
+
104
+ name 'group'
105
+
106
+ # properties
107
+ property(:id, 0) { |p| p.to_s.to_i == p }
108
+ link_property(:owner, UserModelItem)
109
+
110
+ def initialize(model, path)
111
+ super
112
+ @users = GitDS::ProxyItemList.new(UserModelItem, model, path)
113
+ end
114
+
115
+ # Use :name entry in Hash as primary key
116
+ # NOTE: This tests overriding of ident() instead of ident_key()
117
+ def self.ident(args)
118
+ args[:name]
119
+ end
120
+
121
+ alias :name :ident
122
+
123
+ def id
124
+ integer_property(:id)
125
+ end
126
+
127
+ def id=(val)
128
+ set_property(:id, val)
129
+ end
130
+
131
+ def owner
132
+ get_property(:owner)
133
+ end
134
+
135
+ def owner=(u)
136
+ set_property(:owner, u)
137
+ end
138
+
139
+ def users
140
+ ensure_valid
141
+ @users.keys
142
+ end
143
+
144
+ def user(name)
145
+ ensure_valid
146
+ @users[name]
147
+ end
148
+
149
+ def add_user(u)
150
+ @users.add(self, u, true)
151
+ end
152
+
153
+ def del_user(name)
154
+ @users.delete(name)
155
+ end
156
+ end
157
+
158
+
159
+ # =============================================================================
160
+ class TC_GitUserGroupModelTest < Test::Unit::TestCase
161
+ TMP = File.dirname(__FILE__) + File::SEPARATOR + 'tmp'
162
+
163
+ attr_reader :db, :model
164
+
165
+ def setup
166
+ FileUtils.remove_dir(TMP) if File.exist?(TMP)
167
+ Dir.mkdir(TMP)
168
+ path = TMP + File::SEPARATOR + 'ug_model_test'
169
+ @db = GitDS::Database.new(path)
170
+ @model = GitDS::Model.new(@db)
171
+ end
172
+
173
+ def teardown
174
+ FileUtils.remove_dir(TMP) if File.exist?(TMP)
175
+ end
176
+
177
+ # ----------------------------------------------------------------------
178
+ def test_user_item
179
+ assert_equal(0, UserModelItem.list(@model.root).count, 'init # Users not 0')
180
+
181
+ args = { :username => 'admin', :id => 1,
182
+ :roles => [ {:ident => 'sysadmin', :auth => 255},
183
+ {:ident => 'operator'} ]
184
+ }
185
+ path = UserModelItem.create(@model.root, args)
186
+ assert_equal(1, UserModelItem.list(@model.root).count, 'User not created')
187
+
188
+ # User should exist on filesystem
189
+ @db.exec_in_git_dir {
190
+ assert(::File.exist?(path), 'UserModelItem.create failed')
191
+ }
192
+
193
+ assert( @model.exist?(path), 'User not created in object database' )
194
+ assert_equal(2, @model.list_children(path).count, 'User prop not created')
195
+ assert_equal(1, UserModelItem.list(@model.root).count, '>1 Users exist')
196
+
197
+ # Role should exist in database
198
+ role_path = path + File::SEPARATOR + 'role'
199
+ assert_equal(2, @model.list_children(role_path).count)
200
+
201
+ auth_path = role_path + File::SEPARATOR + 'sysadmin' + File::SEPARATOR +
202
+ 'auth'
203
+ assert( @model.exist?(auth_path) )
204
+
205
+ u = UserModelItem.new(@model, path)
206
+ assert_equal(args[:username], u.ident, 'User ident was not set')
207
+ assert_equal(args[:username], u.username, 'User username was not set')
208
+ assert_equal(args[:id], u.id, 'User property id was not set')
209
+ # try again after cache
210
+ assert_equal(args[:id], u.id, 'User property id was not cached')
211
+ assert_equal(args[:id], u.property_cache[:id], 'Cached property is wrong')
212
+
213
+ u.id = 5
214
+ assert_equal(5, u.id, 'User property id was not changed')
215
+ assert_equal(5, u.property_cache[:id], 'User property id was not changed')
216
+
217
+ # Verify that role accessor works
218
+ assert_equal(2, u.roles.count, 'Incorrect number of User roles')
219
+ assert_equal(['operator', 'sysadmin'], u.roles, 'Incorrect User roles')
220
+ assert_equal('operator', u.role('operator').ident, 'Incorrect role ident')
221
+ assert_equal(255, u.role('sysadmin').auth, 'Incorrect role auth')
222
+
223
+ u.role('operator').auth = 6
224
+ assert_equal(6, u.role('operator').auth, 'Role auth did not get set')
225
+
226
+ u.add_role('sucker', 7)
227
+ assert_equal(3, u.roles.count, 'User role did not get added')
228
+ assert_equal(['operator', 'sucker', 'sysadmin'], u.roles,
229
+ 'Incorrect User roles after add')
230
+ assert_equal(7, u.role('sucker').auth, 'Role auth did not get set on add')
231
+
232
+ u.role('sucker').delete
233
+ assert_equal(2, u.roles.count, 'User role did not get deleted')
234
+ assert_equal(['operator', 'sysadmin'], u.roles, 'Incorrect User roles')
235
+
236
+ u.delete
237
+ assert( (not @model.exist? path) )
238
+ assert_equal(0, UserModelItem.list(@model.root).count, '>0 Users exist')
239
+
240
+ assert_raises(GitDS::InvalidModelItemError, 'Deleted item still usable') {
241
+ u.id
242
+ }
243
+ assert_raises(GitDS::InvalidModelItemError, 'Deleted item still usable') {
244
+ u.username
245
+ }
246
+ assert_raises(GitDS::InvalidModelItemError, 'Deleted item still usable') {
247
+ u.delete
248
+ }
249
+ end
250
+
251
+ # ----------------------------------------------------------------------
252
+ def test_group
253
+ assert_equal(0, GroupModelItem.list(@model.root).count, 'init # Groups > 0')
254
+
255
+ args = { :name => 'staff', :id => 1000 }
256
+ path = GroupModelItem.create(@model.root, args)
257
+ assert_equal(1, GroupModelItem.list(@model.root).count, 'Group not created')
258
+
259
+ # Group should exist on filesystem
260
+ @db.exec_in_git_dir {
261
+ assert(::File.exist?(path), 'GroupModelItem.create failed')
262
+ }
263
+
264
+ assert( @model.exist?(path), 'Group not created in object database' )
265
+ assert_equal(1, @model.list_children(path).count, 'Group prop not created')
266
+ assert_equal(1, GroupModelItem.list(@model.root).count, '>1 Groups exist')
267
+
268
+ g = GroupModelItem.new(@model, path)
269
+
270
+ assert_equal(0, g.users.count, 'User count > 0 in new group')
271
+
272
+ user_defs = [
273
+ { :username => 'admin', :id => 1,
274
+ :roles => [{:ident => 'sysadmin', :auth => 255}, {:ident => 'operator'}]
275
+ },
276
+ { :username => 'bob', :id => 2,
277
+ :roles => [{:ident => 'sysadmin', :auth => 1}, {:ident => 'operator'}]
278
+ },
279
+ { :username => 'bill', :id => 3,
280
+ :roles => [{:ident => 'sysadmin', :auth => 127}, {:ident => 'operator'}]
281
+ },
282
+ { :username => 'jane', :id => 4,
283
+ :roles => [{:ident => 'sysadmin', :auth => 15}, {:ident => 'operator'}]
284
+ }
285
+ ]
286
+ user_defs.each do |u|
287
+ u[:path] = UserModelItem.create(@model.root, u)
288
+ u[:obj] = UserModelItem.new(@model, u[:path])
289
+ g.add_user(u[:obj])
290
+ end
291
+
292
+ assert_equal(user_defs.count, g.users.count, 'Bad User count new group')
293
+
294
+ assert_equal(user_defs.inject([]){ |arr, u| arr << u[:username] }.sort,
295
+ g.users, 'Group user list does not match')
296
+
297
+ g.del_user('jane')
298
+ assert_equal(user_defs.count - 1, g.users.count, 'User not deleted!')
299
+
300
+ # cleanup
301
+ user_defs.each { |u| u[:obj].delete }
302
+
303
+ g.delete
304
+ assert( (not @model.exist? path) )
305
+ assert_equal(0, GroupModelItem.list(@model.root).count, '>0 Groups exist')
306
+
307
+ assert_raises(GitDS::InvalidModelItemError, 'Deleted item still usable') {
308
+ g.id
309
+ }
310
+ assert_raises(GitDS::InvalidModelItemError, 'Deleted item still usable') {
311
+ g.delete
312
+ }
313
+ end
314
+
315
+ end
316
+