treet 0.8.2 → 0.10.2

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,22 +1,17 @@
1
1
  # encoding: UTF-8
2
- require "spec_helper"
2
+ require "test_helper"
3
3
 
4
4
  describe "Repository Farm" do
5
5
  it "should export as array of hashes with an xref value" do
6
6
  farm = Treet::Farm.new(:root => "#{File.dirname(__FILE__)}/../repos/farm1", :xref => 'test')
7
- farm.export.should == [
7
+ farm.repos.count.must_equal 2
8
+ farm.export.must_equal [
8
9
  {
9
10
  'name' => {
10
11
  'full' => 'John Bigbooté'
11
- },
12
- 'xref' => {
13
- 'test' => 'one'
14
12
  }
15
13
  },
16
14
  {
17
- 'xref' => {
18
- 'test' => 'two'
19
- },
20
15
  'name' => {
21
16
  'full' => 'John Smallberries',
22
17
  'first' => 'John',
@@ -39,26 +34,34 @@ describe "Repository Farm" do
39
34
  it "planting should create a directory of UUID-labeled repos" do
40
35
  farm = Treet::Farm.plant(:json => "#{File.dirname(__FILE__)}/../json/master.json", :root => Dir.mktmpdir)
41
36
 
42
- Dir.glob("#{farm.root}/*").count.should == 3
43
- Dir.glob("#{farm.root}/*/emails/*").count.should == 5
44
- Dir.glob("#{farm.root}/*/addresses/*").count.should == 1
37
+ Dir.glob("#{farm.root}/*").count.must_equal 3
38
+ Dir.glob("#{farm.root}/*/emails/*").count.must_equal 5
39
+ Dir.glob("#{farm.root}/*/addresses/*").count.must_equal 1
45
40
 
46
41
  FileUtils.rm_rf(farm.root)
47
42
  end
48
43
 
49
- it "should be retrievable by repo label/xref" do
50
- farm = Treet::Farm.new(:root => "#{File.dirname(__FILE__)}/../repos/farm1", :xref => 'test')
51
- farm['two'].root.should == "#{File.dirname(__FILE__)}/../repos/farm1/two"
52
- farm['two'].to_hash['xref'].should == {'test' => 'two'}
53
- end
44
+ # it "should be retrievable by repo label/xref" do
45
+ # farm = Treet::Farm.new(:root => "#{File.dirname(__FILE__)}/../repos/farm1", :xref => 'test')
46
+ # farm['two'].root.must_equal "#{File.dirname(__FILE__)}/../repos/farm1/two"
47
+ # farm['two'].to_hash['xref'].must_equal {'test' => 'two'}
48
+ # end
54
49
 
55
50
  it "should take additions" do
56
51
  farm = Treet::Farm.plant(:json => "#{File.dirname(__FILE__)}/../json/master.json", :root => Dir.mktmpdir)
52
+ farm.repos.count.must_equal 3
57
53
 
58
54
  bob_hash = load_json("bob1")
59
55
  repo = farm.add(bob_hash)
60
- repo.root.should =~ /#{farm.root}/
61
- Dir.glob("#{farm.root}/*").count.should == 4
56
+ repo.root.must_match /#{farm.root}/
57
+ Dir.glob("#{farm.root}/*").count.must_equal 4
58
+
59
+ farm.repos.count.must_equal 4
60
+
61
+ # now try with a predefined ID
62
+ repo = farm.add(bob_hash, :id => '12345')
63
+ repo.root.must_equal "#{farm.root}/12345"
64
+ Dir.glob("#{farm.root}/*").count.must_equal 5
62
65
 
63
66
  FileUtils.rm_rf(farm.root)
64
67
  end
@@ -0,0 +1,63 @@
1
+ # encoding: UTF-8
2
+ require "test_helper"
3
+ require "pp"
4
+
5
+ describe Treet::Gitfarm do
6
+ def self.empty_gitfarm
7
+ f = Treet::Gitfarm.new(
8
+ :root => Dir.mktmpdir('farm', $topdir),
9
+ :xref => 'testapp',
10
+ :author => {:name => 'Bob', :email => 'bob@example.com'}
11
+ )
12
+ # puts "MADE AN EMPTY FARM OF #{f.repotype}"
13
+ f
14
+ end
15
+
16
+ describe "a directory of labeled git repos" do
17
+ def self.plantfarm
18
+ @farm ||= Treet::Gitfarm.plant(
19
+ :json => jsonfile('master'),
20
+ :root => Dir.mktmpdir('farm', $topdir),
21
+ :author => {:name => 'Bob', :email => 'bob@example.com'},
22
+ :xref => 'myapp'
23
+ )
24
+ end
25
+
26
+ let(:farm) { self.class.plantfarm }
27
+
28
+ it "should be populated" do
29
+ farm.repos.count.must_equal 3
30
+ end
31
+
32
+ it "should all be gitified" do
33
+ farm.repos.each do |id, repo|
34
+ repo.head.wont_be_nil
35
+ repo.tags.must_be_empty
36
+ end
37
+ end
38
+ end
39
+
40
+ describe "new repo in empty farm" do
41
+ def self.dofarm
42
+ @farm ||= begin
43
+ farm = empty_gitfarm
44
+ farm.add(load_json('bob1'), :tag => "app1")
45
+ farm
46
+ end
47
+ end
48
+
49
+ let(:farm) { self.class.dofarm }
50
+
51
+ it "is the only repo" do
52
+ farm.repos.count.must_equal 1
53
+ end
54
+
55
+ it "can be tagged" do
56
+ farm.must_be_instance_of Treet::Gitfarm
57
+ bob = farm.repos.values.first
58
+ bob.wont_be_nil
59
+ bob.must_be_instance_of Treet::Gitrepo
60
+ bob.tags.first.name.must_equal 'refs/tags/app1'
61
+ end
62
+ end
63
+ end
@@ -0,0 +1,346 @@
1
+ # encoding: UTF-8
2
+ require "test_helper"
3
+ require "pp"
4
+
5
+ # convert a hash to a gitrepo
6
+ # convert a plain repo to a gitrepo
7
+ # convert a gitrepo to a plain repo
8
+ # initialize a treet git from an existing gitrepo (with a treet::repo structure)
9
+ # patch a gitrepo (with commit) - verify commit structure
10
+ # pulling past snapshots
11
+
12
+ describe Treet::Gitrepo do
13
+ def self.make_gitrepo(filename, opts = {})
14
+ thash = Treet::Hash.new(load_json(filename))
15
+ trepo = thash.to_repo(Dir.mktmpdir('repo', $topdir))
16
+ Treet::Gitrepo.new(trepo.root, opts)
17
+ end
18
+
19
+ def make_gitrepo(filename, opts = {})
20
+ self.class.make_gitrepo(filename, opts)
21
+ end
22
+
23
+ def hashalike(h1, h2)
24
+ Treet::Hash.diff(h1, h2).empty?
25
+ end
26
+
27
+ describe "creation" do
28
+ it "must have an author" do
29
+ ->{ make_gitrepo('one') }.must_raise(ArgumentError, "xxx")
30
+ end
31
+
32
+ # TODO: must have an existing & non-empty directory tree
33
+ end
34
+
35
+ describe "a minimal non-empty untagged gitrepo" do
36
+ def self.make_johnb
37
+ @memo ||= begin
38
+ data = {
39
+ "name" => {
40
+ "full" => "John Bigbooté"
41
+ }
42
+ }
43
+ thash = Treet::Hash.new(data)
44
+ trepo = thash.to_repo(Dir.mktmpdir('repo', $topdir))
45
+ Treet::Gitrepo.new(trepo.root, :author => {:name => 'Bob', :email => 'bob@example.com'})
46
+ end
47
+ end
48
+
49
+ let(:johnb) { self.class.make_johnb }
50
+
51
+ it "should have exactly one commit" do
52
+ johnb.head.wont_be_nil
53
+ johnb.refs.count.must_equal 1
54
+ johnb.refs.first.target.must_equal johnb.head.target
55
+ r = Rugged::Repository.new(johnb.root)
56
+ r.lookup(johnb.head.target).parents.must_be_empty
57
+ end
58
+
59
+ it "should have a single entry" do
60
+ johnb.index.count.must_equal 1
61
+ johnb.entries.must_equal ['name']
62
+ end
63
+
64
+ it "should fetch data content" do
65
+ johnb.to_hash.must_equal load_json('one')
66
+ end
67
+
68
+ it "should have no tags" do
69
+ johnb.tags.must_be_empty
70
+ end
71
+
72
+ it "should fail on unknown tag lookups" do
73
+ ->{johnb.to_hash(:tag => 'nosuchtag')}.must_raise ArgumentError
74
+ end
75
+
76
+ it "should have no branches" do
77
+ johnb.branches.must_be_empty
78
+ end
79
+
80
+ it "should return commit SHA for version label" do
81
+ johnb.version.must_equal johnb.head.target
82
+ end
83
+
84
+ it "should return nil for unknown tag versions" do
85
+ johnb.version(:tag => 'nosuchtag').must_be_nil
86
+ end
87
+ end
88
+
89
+
90
+ describe "a patched gitrepo" do
91
+ def self.patch_johnb
92
+ @memo ||= begin
93
+ data = {
94
+ "name" => {
95
+ "full" => "John Bigbooté"
96
+ }
97
+ }
98
+ thash = Treet::Hash.new(data)
99
+ trepo = thash.to_repo(Dir.mktmpdir('repo', $topdir))
100
+ r = Treet::Gitrepo.new(trepo.root, :author => {:name => 'Bob', :email => 'bob@example.com'})
101
+ r.patch([
102
+ [
103
+ "+",
104
+ "org.name",
105
+ "Bigcorp"
106
+ ]
107
+ ])
108
+ r
109
+ end
110
+ end
111
+
112
+ let(:repo) { self.class.patch_johnb }
113
+
114
+ it "should have correct git index" do
115
+ repo.index.count.must_equal 2
116
+ repo.entries.must_include 'name'
117
+ repo.entries.must_include 'org'
118
+ end
119
+
120
+ it "should hashify correctly" do
121
+ expectation = load_json('one').merge({'org' => {'name' => 'Bigcorp'}})
122
+ repo.to_hash.must_equal expectation
123
+ end
124
+
125
+ it "should have 2 commits" do
126
+ r = Rugged::Repository.new(repo.root)
127
+ latest_commit = r.head.target
128
+ r.lookup(latest_commit).parents.count.must_equal 1
129
+ previous_commit = r.lookup(latest_commit).parents.first
130
+ previous_commit.parents.must_be_empty
131
+ end
132
+
133
+ it "should have no tags" do
134
+ repo.tags.must_be_empty
135
+ end
136
+
137
+ # it "should be able to reverse-engineer the patch from the git history" do
138
+ # skip
139
+ # # rugged has a `Rugged::Commit#diff-tree` on the roadmap (see `USAGE.rb`), not yet implemented
140
+ # end
141
+ end
142
+
143
+ describe "patched with a delete" do
144
+ let(:repo) do
145
+ r = make_gitrepo('two', :author => {:name => 'Bob', :email => 'bob@example.com'})
146
+ r.patch([
147
+ [
148
+ "-",
149
+ "emails[]",
150
+ { "label" => "home", "email" => "johns@lectroid.com" }
151
+ ]
152
+ ])
153
+ r
154
+ end
155
+
156
+ it "should have correct git index" do
157
+ repo.index.count.must_equal 2
158
+ repo.entries.must_include 'name'
159
+ repo.entries.grep(/emails/).wont_be_empty
160
+ end
161
+
162
+ it "should hashify correctly" do
163
+ # should reflect the deletion in current state
164
+ expectation = load_json('two')
165
+ expectation['emails'].delete_if {|v| v['label'] == 'home'}
166
+ repo.to_hash.must_equal expectation
167
+ end
168
+
169
+ it "should have 2 commits" do
170
+ r = Rugged::Repository.new(repo.root)
171
+ latest_commit = r.head.target
172
+ r.lookup(latest_commit).parents.count.must_equal 1
173
+ previous_commit = r.lookup(latest_commit).parents.first
174
+ previous_commit.parents.must_be_empty
175
+ end
176
+
177
+ it "should show the original state in the previous commit" do
178
+ r = Rugged::Repository.new(repo.root)
179
+ latest_commit = r.head.target
180
+ r.lookup(latest_commit).parents.count.must_equal 1
181
+ previous_commit = r.lookup(latest_commit).parents.first
182
+ assert hashalike(repo.to_hash(:commit => previous_commit.oid), load_json('two'))
183
+ end
184
+ end
185
+
186
+ describe "a tagged & patched repo" do
187
+ def self.makerepo
188
+ @cache ||= begin
189
+ r = make_gitrepo('two',
190
+ :author => {:name => 'Bob', :email => 'bob@example.com'},
191
+ :xrefkey => 'app1',
192
+ :xref => 'APP1_ID'
193
+ )
194
+ r.tag('app1')
195
+ r.patch([
196
+ [
197
+ "-",
198
+ "emails[]",
199
+ { "label" => "home", "email" => "johns@lectroid.com" }
200
+ ],
201
+ [
202
+ "+",
203
+ "name.first",
204
+ "Ralph"
205
+ ]
206
+ ])
207
+ r
208
+ end
209
+ end
210
+
211
+ let(:repo) { self.class.makerepo }
212
+
213
+ it "should correctly commit the existing updated git artifacts" do
214
+ repo.to_hash(:commit => repo.head.target)['name']['first'].must_equal 'Ralph'
215
+ end
216
+
217
+ it "should not have an index entry for the removed item" do
218
+ repo.entries.must_include 'name'
219
+ repo.entries.grep(/^emails/).wont_be_empty
220
+ repo.index.count.must_equal 2
221
+ end
222
+
223
+ it "should have tag not pointing to HEAD" do
224
+ repo.tags.count.must_equal 1
225
+ repo.tags.first.name.must_equal "refs/tags/app1"
226
+ repo.tags.first.target.wont_equal repo.head.target
227
+ end
228
+
229
+ it "should have the original image for the tag" do
230
+ refute hashalike(repo.to_hash, repo.to_hash(:tag => 'app1'))
231
+ assert hashalike(repo.to_hash(:tag => 'app1'), load_json('two'))
232
+ end
233
+
234
+ it "should have no branches" do
235
+ repo.branches.must_be_empty
236
+ end
237
+
238
+ it "should track version label by tag" do
239
+ repo.version.must_equal repo.head.target
240
+ repo.version(:tag => 'app1').must_equal repo.tags.first.target
241
+ end
242
+ end
243
+
244
+ describe "a tagged repo" do
245
+ let(:repo) do
246
+ r = make_gitrepo('two', :author => {:name => 'Bob', :email => 'bob@example.com'})
247
+ r.tag('source1')
248
+ r
249
+ end
250
+
251
+ it "should have tags" do
252
+ repo.tags.count.must_equal 1
253
+ repo.tags.first.name.must_equal "refs/tags/source1"
254
+ end
255
+
256
+ it "should have no branches" do
257
+ repo.branches.must_be_empty
258
+ end
259
+
260
+ it "should retrieve same image for default and by tag" do
261
+ assert hashalike(repo.to_hash(:tag => 'source1'), load_json('two'))
262
+ end
263
+
264
+ it "should point the tag at the commit" do
265
+ repo.tags.first.target.must_equal repo.head.target
266
+ repo.version.must_equal repo.version(:tag => 'source1')
267
+ end
268
+ end
269
+
270
+ describe "a multiply-patched gitrepo" do
271
+ def self.makerepo
272
+ @cache ||= begin
273
+ r = make_gitrepo('two', :author => {:name => 'Bob', :email => 'bob@example.com'})
274
+ r.tag('app1')
275
+ r.tag('app2')
276
+ image1 = r.to_hash
277
+ r.patch([
278
+ [
279
+ "+",
280
+ "org.name",
281
+ "BigCorp"
282
+ ]
283
+ ])
284
+ r.tag('app2')
285
+ image2 = r.to_hash
286
+ r.patch([
287
+ [
288
+ "-",
289
+ "org.name",
290
+ "BigCorp"
291
+ ]
292
+ ])
293
+ r.tag('app3')
294
+ image3 = r.to_hash
295
+ r.patch([
296
+ [
297
+ "-",
298
+ "emails[]",
299
+ { "label" => "home", "email" => "johns@lectroid.com" }
300
+ ]
301
+ ])
302
+ r.tag('app4')
303
+ image4 = r.to_hash
304
+
305
+ {
306
+ :repo => r,
307
+ :image1 => image1,
308
+ :image2 => image2,
309
+ :image3 => image3,
310
+ :image4 => image4
311
+ }
312
+ end
313
+ end
314
+
315
+ let(:repo) { self.class.makerepo }
316
+
317
+ it "should remember all the tags" do
318
+ repo[:repo].tags.count.must_equal 4
319
+ end
320
+
321
+ it "should fetch different images by tag" do
322
+ assert hashalike(repo[:repo].to_hash(:tag => 'app1'), repo[:image1])
323
+ assert hashalike(repo[:repo].to_hash(:tag => 'app2'), repo[:image2])
324
+ assert hashalike(repo[:repo].to_hash(:tag => 'app3'), repo[:image3])
325
+ assert hashalike(repo[:repo].to_hash(:tag => 'app4'), repo[:image4])
326
+ assert hashalike(repo[:repo].to_hash, repo[:image4])
327
+ end
328
+
329
+ it "should have different version labels for each tag" do
330
+ versions = ['app1', 'app2', 'app3', 'app4'].map {|s| repo[:repo].version(:tag => s)}
331
+ versions.uniq.count.must_equal 4
332
+ end
333
+ end
334
+
335
+ describe "a branched gitrepo" do
336
+ let(:repo) do
337
+ r = make_gitrepo('one', :author => {:name => 'Bob', :email => 'bob@example.com'})
338
+ r.branch('mybranch')
339
+ r
340
+ end
341
+
342
+ it "should show a branch" do
343
+ repo.branches.must_equal ['refs/heads/mybranch']
344
+ end
345
+ end
346
+ end
@@ -0,0 +1,25 @@
1
+ require 'minitest/spec'
2
+
3
+ require File.expand_path('../../lib/treet', __FILE__)
4
+
5
+ require "tmpdir"
6
+ require "fileutils"
7
+
8
+ $topdir ||= Dir.mktmpdir("treet-tests-")
9
+
10
+ def jsonfile(filename)
11
+ "#{File.dirname(__FILE__)}/json/#{filename}.json"
12
+ end
13
+
14
+ def load_json(filename)
15
+ JSON.load(File.open(jsonfile(filename)))
16
+ end
17
+
18
+ MiniTest::Unit.after_tests do
19
+ $stderr.puts "Erasing #{$topdir}"
20
+ FileUtils.rm_rf $topdir
21
+ $topdir = nil
22
+ end
23
+
24
+ # MUST PUT THIS AT *END* OF FILE OR CLEANUP WILL HAPPEN BEFORE TESTS ARE RUN!
25
+ require 'minitest/autorun'
data/treet.gemspec CHANGED
@@ -15,10 +15,12 @@ Gem::Specification.new do |gem|
15
15
  gem.require_paths = ["lib"]
16
16
  gem.version = Treet::VERSION
17
17
 
18
- gem.add_dependency 'uuidtools'
18
+ gem.add_dependency 'thor'
19
+ gem.add_dependency 'rugged', "~> 0.17.0.b6"
19
20
 
20
- gem.add_development_dependency "rake", "~> 0.9.2"
21
- gem.add_development_dependency "rspec", "~> 2.9.0"
22
- gem.add_development_dependency "guard-rspec", "~> 0.7.0"
23
- gem.add_development_dependency "ruby_gntp", "~> 0.3.4"
21
+ gem.add_development_dependency "rake"
22
+ gem.add_development_dependency "rspec"
23
+ gem.add_development_dependency "guard-rspec"
24
+ gem.add_development_dependency "guard-minitest"
25
+ gem.add_development_dependency "ruby_gntp"
24
26
  end