| OLD | NEW |
| (Empty) | |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. |
| 4 |
| 5 package git |
| 6 |
| 7 import ( |
| 8 "fmt" |
| 9 "strings" |
| 10 "testing" |
| 11 |
| 12 . "github.com/smartystreets/goconvey/convey" |
| 13 |
| 14 "infra/libs/infra_util" |
| 15 ) |
| 16 |
| 17 type FakeGitEntry struct { |
| 18 data string |
| 19 typ ObjectType |
| 20 size int |
| 21 } |
| 22 |
| 23 type FakeGitService map[ObjectID]FakeGitEntry |
| 24 |
| 25 func (f FakeGitService) GetObjectID(id Identifiable) (InternableObject, error) { |
| 26 if id.ID().RawString() == "TestsFailureObjectID" { |
| 27 return &Blob{}, fmt.Errorf("Cannot get TestsFailureObjectID") |
| 28 } |
| 29 obj, ok := f[*id.ID()] |
| 30 if !ok { |
| 31 return nil, nil |
| 32 } |
| 33 return ObjectFromRawWithID(id, obj.typ, []byte(obj.data)) |
| 34 } |
| 35 |
| 36 func (f FakeGitService) HasObjectID(id Identifiable) bool { |
| 37 o, _ := f.GetObjectID(id) |
| 38 return o != nil |
| 39 } |
| 40 |
| 41 func (f FakeGitService) ObjectInfo(objectish string) *ObjectInfo { |
| 42 // technically this needs to implement all of rev-parse, but we'll just |
| 43 // cheat for the bits we need right now (e.g. <hash>:) |
| 44 id, err := MakeObjectIDErr(objectish[:len(objectish)-1]) |
| 45 if err != nil { |
| 46 Println("FakeGitService cannot process", objectish) |
| 47 return nil |
| 48 } |
| 49 if objectish[len(objectish)-1] == ':' { |
| 50 o, err := f.GetObjectID(id) |
| 51 if err != nil { |
| 52 return nil |
| 53 } |
| 54 if commit, ok := o.(*Commit); !ok { |
| 55 Println("Has is not a commit", objectish) |
| 56 return nil |
| 57 } else { |
| 58 return f.ObjectInfoID(commit.Tree()) |
| 59 } |
| 60 } else { |
| 61 Println("FakeGitService cannot process", objectish) |
| 62 return nil |
| 63 } |
| 64 } |
| 65 |
| 66 func (f FakeGitService) ObjectInfoID(id Identifiable) *ObjectInfo { |
| 67 obj, ok := f[*id.ID()] |
| 68 if !ok { |
| 69 return nil |
| 70 } |
| 71 return &ObjectInfo{obj.typ, obj.size, id.ID()} |
| 72 } |
| 73 |
| 74 func (f FakeGitService) Intern(o InternableObject) (*ObjectID, error) { |
| 75 return InternImpl(f, o, func(data string) (string, error) { |
| 76 f[*o.ID()] = FakeGitEntry{data, o.Type(), len(data)} |
| 77 return o.ID().String(), nil |
| 78 }) |
| 79 } |
| 80 |
| 81 func TestTree(t *testing.T) { |
| 82 t.Parallel() |
| 83 |
| 84 Convey("Tree", t, func() { |
| 85 |
| 86 Convey("Constructors", func() { |
| 87 |
| 88 Convey("Text", func() { |
| 89 |
| 90 Convey("Should parse", func() { |
| 91 txt := strings.Join([]string{ |
| 92 "100644 blob 302296b172eb2152d24
9734ed93690c7213f0ea0\t.gitignore", |
| 93 "100644 blob d0225511d9de0193a95
f81900c70cbc50b759818\t.gitmodules", |
| 94 "100644 blob dcd5f302bb21c46488d
813a57a543f6afa94b8b4\t.netrwhist", |
| 95 "040000 tree c7dcb4bbcdaf65ea75e
a7735c7694d412f66ddb6\tAudio", |
| 96 "160000 commit 3bb7c33fbb5721e2b
e5ff963f8f3ba78e4878983\tLS_COLORS", |
| 97 "100644 blob 1402d9c72db11e48bb1
5a5c4163e5fbbbd1a6218\tREADME.md", |
| 98 "040000 tree 3bfce6fec987eb7a424
34e15a7033c7818c684fe\tUltiSnips", |
| 99 }, "\n") |
| 100 |
| 101 tree, err := NewTreeFromText([]byte(txt)
) |
| 102 So(err, ShouldBeNil) |
| 103 So(tree.Type(), ShouldEqual, TreeType) |
| 104 So(tree.NumChildren(), ShouldEqual, 7) |
| 105 |
| 106 So(tree.Complete(), ShouldBeTrue) |
| 107 So(tree.ID().String(), ShouldEqual, "279
32b52d6c0f6381fbfe8505d08ee45c33b7b88") |
| 108 }) |
| 109 |
| 110 Convey("Should parse with quoted paths", func()
{ |
| 111 txt := "100644 blob 302296b172eb2152d249
734ed93690c7213f0ea0\t\"foo\\nbar\"\n" |
| 112 |
| 113 tree, err := NewTreeFromText([]byte(txt)
) |
| 114 So(err, ShouldBeNil) |
| 115 So(tree.NumChildren(), ShouldEqual, 1) |
| 116 |
| 117 c := tree.GetChild("foo\nbar") |
| 118 So(c, ShouldNotBeNil) |
| 119 So(c.Object.Type(), ShouldEqual, BlobTyp
e) |
| 120 }) |
| 121 |
| 122 Convey("Should reject bad text", func() { |
| 123 bads := []string{ |
| 124 "", |
| 125 "100644 blob nubsauce\t\"wat\"\n
", |
| 126 "hi blob 302296b172eb2152d249734
ed93690c7213f0ea0\t\"wat\"\n", |
| 127 "100644 blob 302296b172eb2152d24
9734ed93690c7213f0ea0\t\"wat\n", |
| 128 "100644 blob 302296b172eb2152d24
9734ed93690c7213f0ea0 bob\n", |
| 129 "blob 302296b172eb2152d249734ed9
3690c7213f0ea0\tbob\n", |
| 130 "100644 302296b172eb2152d249734e
d93690c7213f0ea0\tbob\n", |
| 131 "0 blob 302296b172eb2152d249734e
d93690c7213f0ea0\tbob\n", |
| 132 "100644 blob 302296b172eb2152d24
9734ed93690c7213f0ea0\t\n", |
| 133 } |
| 134 for _, txt := range bads { |
| 135 txt := txt |
| 136 Convey(fmt.Sprintf("%#v", txt),
func() { |
| 137 _, err := NewTreeFromTex
t([]byte(txt)) |
| 138 So(err, ShouldNotBeNil) |
| 139 }) |
| 140 } |
| 141 }) |
| 142 |
| 143 Convey("Should reject nil", func() { |
| 144 _, err := NewTreeFromText(nil) |
| 145 So(err, ShouldNotBeNil) |
| 146 }) |
| 147 }) |
| 148 |
| 149 Convey("Binary", func() { |
| 150 |
| 151 Convey("Should parse", func() { |
| 152 bin := strings.Join([]string{ |
| 153 "100644 .gitignore\x000\"\x96\xb
1r\xeb!R\xd2IsN\xd96\x90\xc7!?\x0e\xa0", |
| 154 "100644 .gitmodules\x00\xd0\"U\x
11\xd9\xde\x01\x93\xa9_\x81\x90\x0cp\xcb\xc5\x0bu\x98\x18", |
| 155 "100644 .netrwhist\x00\xa3\xea\x
dd\x97*\x16\x08\x88\x11\x17\xee7I\x8a\t\xb1\xbd\x82et", |
| 156 "40000 Audio\x00\xc7\xdc\xb4\xbb
\xcd\xafe\xeau\xeaw5\xc7iMA/f\xdd\xb6", |
| 157 "160000 LS_COLORS\x00;\xb7\xc3?\
xbbW!\xe2\xbe_\xf9c\xf8\xf3\xbax\xe4\x87\x89\x83", |
| 158 "100644 README.md\x00\x14\x02\xd
9\xc7-\xb1\x1eH\xbb\x15\xa5\xc4\x16>_\xbb\xbd\x1ab\x18", |
| 159 "40000 UltiSnips\x00;\xfc\xe6\xf
e\xc9\x87\xebzBCN\x15\xa7\x03<x\x18\xc6\x84\xfe", |
| 160 }, "") |
| 161 |
| 162 tree, err := NewTreeFromRaw([]byte(bin)) |
| 163 So(err, ShouldBeNil) |
| 164 So(tree.NumChildren(), ShouldEqual, 7) |
| 165 So(tree.ID().String(), ShouldEqual, "c86
f07a67fcfadb63a9686a4bb1851cc4b01d7bc") |
| 166 |
| 167 Convey("Round-trip", func() { |
| 168 So(tree.RawString(), ShouldEqual
, bin) |
| 169 }) |
| 170 }) |
| 171 |
| 172 Convey("Empty should parse", func() { |
| 173 tree, err := NewTreeFromRaw(nil) |
| 174 So(err, ShouldBeNil) |
| 175 So(tree.NumChildren(), ShouldEqual, 0) |
| 176 So(tree.ID().String(), ShouldEqual, Empt
yTreeHash) |
| 177 |
| 178 Convey("Round-trip", func() { |
| 179 So(tree.RawString(), ShouldEqual
, "") |
| 180 }) |
| 181 |
| 182 Convey("Matches NewEmptyTree", func() { |
| 183 empty := NewEmptyTree(&NoID, 0) |
| 184 empty.RawString() // re-calculat
e the empty hash |
| 185 So(empty.ID(), ShouldResemble, t
ree.ID()) |
| 186 }) |
| 187 }) |
| 188 |
| 189 Convey("Should reject bad binaries", func() { |
| 190 bads := []string{ |
| 191 "hi .gitignore\x000\"\x96\xb1r\x
eb!R\xd2IsN\xd96\x90\xc7!?\x0e\xa0", |
| 192 "0 .gitignore\x000\"\x96\xb1r\xe
b!R\xd2IsN\xd96\x90\xc7!?\x0e\xa0", |
| 193 "100644\x000\"\x96\xb1r\xeb!R\xd
2IsN\xd96\x90\xc7!?\x0e\xa0", |
| 194 "100644 bob\x000\"\x96\xb1\xeb!R
\xd2IsN\xd96\x90\xc7!?\x0e\xa0", |
| 195 } |
| 196 for _, bin := range bads { |
| 197 bin := bin |
| 198 Convey(fmt.Sprintf("%#v", bin),
func() { |
| 199 _, err := NewTreeFromRaw
([]byte(bin)) |
| 200 So(err, ShouldNotBeNil) |
| 201 }) |
| 202 } |
| 203 }) |
| 204 }) |
| 205 }) |
| 206 |
| 207 Convey("TreeManipulation", func() { |
| 208 tree := NewEmptyTree(&NoID, 0) |
| 209 |
| 210 Convey("GetChild", func() { |
| 211 names := []string{ |
| 212 "", |
| 213 "bob", |
| 214 "bob\nnewline", |
| 215 "bob/subitem", |
| 216 } |
| 217 for _, name := range names { |
| 218 name := name |
| 219 Convey(fmt.Sprintf("Returns nil with no
children: %#v", name), func() { |
| 220 So(tree.GetChild(name), ShouldBe
Nil) |
| 221 }) |
| 222 } |
| 223 }) |
| 224 |
| 225 Convey("SetChild", func() { |
| 226 Convey("cannot set a child on the empty path", f
unc() { |
| 227 So(func() { tree.SetChild("", BlankTreeC
hild(0)) }, ShouldPanic) |
| 228 }) |
| 229 |
| 230 Convey("can create intermediate trees for a chil
d", func() { |
| 231 c, err := NewEmptyChild(0100644, &NoID) |
| 232 So(err, ShouldBeNil) |
| 233 So(c.Object.Type(), ShouldEqual, BlobTyp
e) |
| 234 tree.SetChild("rootblob", c) |
| 235 tree.SetChild("bob/blob", c) |
| 236 |
| 237 c, err = NewEmptyChild(040000, MakeObjec
tID(EmptyTreeHash)) |
| 238 So(err, ShouldBeNil) |
| 239 tree.SetChild("bob/blank_subtree", c) |
| 240 |
| 241 c, err = NewEmptyChild(040000, MakeObjec
tID("deadbeefdeadbeefdeadbeefdeadbeefdeadbeef")) |
| 242 So(err, ShouldBeNil) |
| 243 tree.SetChild("bob/nonblank_subtree", c) |
| 244 |
| 245 Convey("the tree was set up correctly",
func() { |
| 246 So(tree.NumChildren(), ShouldEqu
al, 2) |
| 247 for k := range tree.children { |
| 248 So(k, ShouldBeIn, []stri
ng{"bob", "rootblob"}) |
| 249 } |
| 250 |
| 251 So(tree.GetChild("bob").Object.(
*Tree).NumChildren(), ShouldEqual, 3) |
| 252 for k := range tree.GetChild("bo
b").Object.(*Tree).children { |
| 253 So(k, ShouldBeIn, []stri
ng{"blank_subtree", "blob", "nonblank_subtree"}) |
| 254 } |
| 255 }) |
| 256 |
| 257 Convey("but will panic if you try to cre
ate a child of a non-tree", func() { |
| 258 So(func() { tree.SetChild("bob/b
lob/fail", BlankTreeChild(0)) }, ShouldPanic) |
| 259 }) |
| 260 |
| 261 Convey("getting the child of a non-tree
is also a panic", func() { |
| 262 So(func() { tree.GetChild("bob/b
lob/fail") }, ShouldPanic) |
| 263 }) |
| 264 |
| 265 Convey("setting a child of a placeholder
tree will panic", func() { |
| 266 So(func() { tree.SetChild("bob/n
onblank_subtree/happy_days", BlankTreeChild(0)) }, ShouldPanic) |
| 267 }) |
| 268 |
| 269 Convey("however, setting a child of an e
mpty placeholder tree will cause it to exist", func() { |
| 270 c, err := NewEmptyChild(0100644,
&NoID) |
| 271 So(err, ShouldBeNil) |
| 272 tree.SetChild("bob/blank_subtree
/happy_days", c) |
| 273 So(tree.GetChild("bob/blank_subt
ree").Object, ShouldHaveSameTypeAs, tree) |
| 274 }) |
| 275 |
| 276 Convey("DelChild", func() { |
| 277 Convey("returns when you delete
something that's not there", func() { |
| 278 So(tree.DelChild("nerd")
, ShouldBeFalse) |
| 279 So(tree.DelChild("whatno
w/sup"), ShouldBeFalse) |
| 280 So(tree.DelChild("bob/no
there"), ShouldBeFalse) |
| 281 }) |
| 282 |
| 283 Convey("but will panic if you tr
y to delete a subordinate of a blob", func() { |
| 284 So(func() { tree.DelChil
d("rootblob/boom") }, ShouldPanic) |
| 285 }) |
| 286 |
| 287 Convey("It will also clean out d
irectories when they are empty", func() { |
| 288 So(tree.DelChild("bob/bl
ank_subtree"), ShouldBeTrue) |
| 289 So(tree.DelChild("bob/no
nblank_subtree"), ShouldBeTrue) |
| 290 So(tree.DelChild("bob/bl
ob"), ShouldBeTrue) |
| 291 So(tree.NumChildren(), S
houldEqual, 1) |
| 292 for k := range tree.chil
dren { |
| 293 So(k, ShouldBeIn
, []string{"rootblob"}) |
| 294 } |
| 295 }) |
| 296 |
| 297 Convey("It can also remove direc
tories with content", func() { |
| 298 So(tree.DelChild("bob"),
ShouldBeTrue) |
| 299 So(tree.NumChildren(), S
houldEqual, 1) |
| 300 for k := range tree.chil
dren { |
| 301 So(k, ShouldBeIn
, []string{"rootblob"}) |
| 302 } |
| 303 }) |
| 304 }) |
| 305 }) |
| 306 |
| 307 Convey("Intern(FakeGitService)", func() { |
| 308 s := make(FakeGitService) |
| 309 |
| 310 Convey("In an empty tree", func() { |
| 311 Convey("allowMissing should succ
eed", func() { |
| 312 id, err := tree.Intern(s
, true) |
| 313 So(err, ShouldBeNil) |
| 314 So(id.String(), ShouldEq
ual, EmptyTreeHash) |
| 315 }) |
| 316 |
| 317 Convey("!allowMissing should suc
ceed", func() { |
| 318 id, err := tree.Intern(s
, true) |
| 319 So(err, ShouldBeNil) |
| 320 So(id.String(), ShouldEq
ual, EmptyTreeHash) |
| 321 }) |
| 322 }) |
| 323 |
| 324 Convey("In a tree with an EmptyObject",
func() { |
| 325 c, err := NewEmptyChild(0100644,
MakeObjectIDForData(BlobType, []byte("sup"))) |
| 326 So(err, ShouldBeNil) |
| 327 tree.SetChild("nest/blob", c) |
| 328 |
| 329 Convey("allowMissing should succ
eed", func() { |
| 330 id, err := tree.Intern(s
, true) |
| 331 So(err, ShouldBeNil) |
| 332 So(id.String(), ShouldEq
ual, "730bdd0d9d5cb610df9b00df7a622cee291a5453") |
| 333 So(len(s), ShouldEqual,
2) |
| 334 }) |
| 335 |
| 336 Convey("!allowMissing should fai
l", func() { |
| 337 _, err := tree.Intern(s,
false) |
| 338 So(err, ShouldNotBeNil) |
| 339 expect := infra_util.Str
ingSetFrom( |
| 340 "ME[\"missing no
n-internable object: EmptyObject(0b90e2b8567ab715f87fb49c6a0a08ce6f2eb312, blob)
\"]") |
| 341 So(err.(*infra_util.Mult
iError).ErrorStrings(), ShouldResemble, expect) |
| 342 So(s, ShouldBeEmpty) |
| 343 }) |
| 344 }) |
| 345 |
| 346 Convey("In a tree with a nested Blob", f
unc() { |
| 347 tree.SetChild("nest/blob", &Chil
d{NewBlobFromRaw([]byte("sup")), Mode(0100644)}) |
| 348 |
| 349 Convey("allowMissing should succ
eed", func() { |
| 350 id, err := tree.Intern(s
, true) |
| 351 So(err, ShouldBeNil) |
| 352 So(id.String(), ShouldEq
ual, "730bdd0d9d5cb610df9b00df7a622cee291a5453") |
| 353 So(len(s), ShouldEqual,
3) |
| 354 }) |
| 355 |
| 356 Convey("!allowMissing should suc
ceed", func() { |
| 357 id, err := tree.Intern(s
, false) |
| 358 So(err, ShouldBeNil) |
| 359 So(id.String(), ShouldEq
ual, "730bdd0d9d5cb610df9b00df7a622cee291a5453") |
| 360 So(len(s), ShouldEqual,
3) |
| 361 }) |
| 362 }) |
| 363 |
| 364 Convey("In a tree with a NoID EmptyObjec
t", func() { |
| 365 c, err := NewEmptyChild(0100644,
&NoID) |
| 366 So(err, ShouldBeNil) |
| 367 tree.SetChild("nest/blob", c) |
| 368 |
| 369 Convey("allowMissing should fail
", func() { |
| 370 _, err := tree.Intern(s,
true) |
| 371 So(err, ShouldNotBeNil) |
| 372 expect := infra_util.Str
ingSetFrom( |
| 373 "ME[\"object has
an ID of <NoID>\"]") |
| 374 So(err.(*infra_util.Mult
iError).ErrorStrings(), ShouldResemble, expect) |
| 375 So(s, ShouldBeEmpty) |
| 376 }) |
| 377 |
| 378 Convey("!allowMissing should fai
l", func() { |
| 379 _, err := tree.Intern(s,
false) |
| 380 So(err, ShouldNotBeNil) |
| 381 expect := infra_util.Str
ingSetFrom( |
| 382 "ME[\"missing no
n-internable object: EmptyObject(<NoID>, blob)\"]") |
| 383 So(err.(*infra_util.Mult
iError).ErrorStrings(), ShouldResemble, expect) |
| 384 So(s, ShouldBeEmpty) |
| 385 }) |
| 386 }) |
| 387 |
| 388 Convey("In a tree with an empty (but ID'
d) subtree", func() { |
| 389 sub_id := "a7d0c997159313b124cf5
daec4715ba59c5993d3" |
| 390 c, err := NewEmptyChild(040000,
MakeObjectID(sub_id)) |
| 391 So(err, ShouldBeNil) |
| 392 tree.SetChild("nest", c) |
| 393 |
| 394 Convey("allowMissing should succ
eed", func() { |
| 395 _, err := tree.Intern(s,
true) |
| 396 So(err, ShouldBeNil) |
| 397 So(len(s), ShouldEqual,
1) |
| 398 |
| 399 Convey("and the subtree
should retain its ID", func() { |
| 400 So(tree.GetChild
("nest").Object.ID().String(), ShouldEqual, sub_id) |
| 401 }) |
| 402 }) |
| 403 |
| 404 Convey("!allowMissing should fai
l", func() { |
| 405 _, err := tree.Intern(s,
false) |
| 406 expect := infra_util.Str
ingSetFrom(fmt.Sprintf( |
| 407 "missing non-int
ernable object: EmptyObject(%s, tree)", sub_id)) |
| 408 So(err, ShouldNotBeNil) |
| 409 So(err.(*infra_util.Mult
iError).ErrorStrings(), ShouldResemble, expect) |
| 410 So(s, ShouldBeEmpty) |
| 411 }) |
| 412 }) |
| 413 }) |
| 414 }) |
| 415 }) |
| 416 |
| 417 Convey("LoadFullTree", func() { |
| 418 s := make(FakeGitService) |
| 419 |
| 420 LT := func(id Identifiable, withBlobs, missingErr bool)
(*Tree, error) { |
| 421 o, err := LoadFullTree(s, id, withBlobs, missing
Err) |
| 422 if err != nil { |
| 423 return nil, err |
| 424 } |
| 425 return o.(*Tree), nil |
| 426 } |
| 427 |
| 428 Convey("with a fully-populated tree", func() { |
| 429 thash := "9fe3bef872f85138118766d83ce0d528fdb522
ad" |
| 430 tree := NewEmptyTree(&NoID, 3) |
| 431 tree.SetChild("sub/blob", &Child{NewBlobFromRaw(
[]byte("hi")), 0100755}) |
| 432 tree.SetChild("sub/happy", &Child{NewBlobFromRaw
([]byte("happy")), 0100755}) |
| 433 tree.SetChild("maybeMissing/blob", &Child{NewBlo
bFromRaw([]byte("sup")), 0100644}) |
| 434 tree.SetChild("nerd", &Child{NewBlobFromRaw([]by
te("hi")), 0100644}) |
| 435 id, err := tree.Intern(s, false) |
| 436 So(err, ShouldBeNil) |
| 437 So(id.String(), ShouldEqual, thash) |
| 438 |
| 439 Convey("Aborts nicely if GetObjectID fails", fun
c() { |
| 440 failID := &ObjectID{} |
| 441 copy(failID.raw[:], "TestsFailureObjectI
D") |
| 442 c, err := NewEmptyChild(040000, failID) |
| 443 So(err, ShouldBeNil) |
| 444 tree.SetChild("fail/failington", c) |
| 445 id, err := tree.Intern(s, false) |
| 446 So(err, ShouldBeNil) |
| 447 wat, err := LT(id, true, true) |
| 448 Print(wat) |
| 449 So(err, ShouldNotBeNil) |
| 450 }) |
| 451 |
| 452 Convey("from a missing tree is an error", func()
{ |
| 453 _, err := LT(MakeObjectIDForData(TreeTyp
e, []byte("bob")), true, true) |
| 454 So(err, ShouldNotBeNil) |
| 455 }) |
| 456 |
| 457 Convey("from a blob is an error", func() { |
| 458 bID, err := s.Intern(NewBlobFromRaw([]by
te("sup"))) |
| 459 So(err, ShouldBeNil) |
| 460 _, err = LT(bID, true, true) |
| 461 So(err, ShouldNotBeNil) |
| 462 }) |
| 463 |
| 464 Convey("from a commit which points to a missing
tree is an error", func() { |
| 465 c, err := NewCommitFromRaw([]byte(fmt.Sp
rintf(`tree %s |
| 466 author Jane Janerton <bob@chromium.org> 123456789 +0000 |
| 467 committer Bob Boberton <bob@chromium.org> 123456789 +0000 |
| 468 |
| 469 Super cool tree commit`, MakeObjectIDForData(TreeType, []byte("bob"))))) |
| 470 So(err, ShouldBeNil) |
| 471 s.Intern(c) |
| 472 _, err = LT(c.ID(), true, true) |
| 473 So(err, ShouldNotBeNil) |
| 474 }) |
| 475 |
| 476 Convey("noBlobs", func() { |
| 477 Convey("missingErr (success)", func() { |
| 478 loaded, err := LT(id, false, tru
e) |
| 479 So(err, ShouldBeNil) |
| 480 Println(loaded.GetChild("nerd")) |
| 481 So(loaded.children, ShouldNotRes
emble, tree.children) |
| 482 for k := range loaded.children { |
| 483 So(k, ShouldBeIn, []stri
ng{"sub", "maybeMissing", "nerd"}) |
| 484 } |
| 485 So(loaded.GetChild("sub").Object
.ID(), ShouldResemble, |
| 486 tree.GetChild("sub").Obj
ect.ID()) |
| 487 So(loaded.GetChild("sub/blob").O
bject.ID(), ShouldResemble, |
| 488 tree.GetChild("sub/blob"
).Object.ID()) |
| 489 So(loaded.GetChild("sub/blob").O
bject, ShouldHaveSameTypeAs, |
| 490 (*EmptyObject)(nil)) |
| 491 }) |
| 492 |
| 493 Convey("removing a tree (maybeMissing)",
func() { |
| 494 mObjID := tree.GetChild("maybeMi
ssing").Object.ID() |
| 495 delete(s, *mObjID) |
| 496 |
| 497 Convey("missingErr", func() { |
| 498 _, err := LT(id, false,
true) |
| 499 So(err, ShouldNotBeNil) |
| 500 }) |
| 501 |
| 502 Convey("allowMissing", func() { |
| 503 loaded, err := LT(id, fa
lse, false) |
| 504 So(err, ShouldBeNil) |
| 505 |
| 506 Println(loaded.GetChild(
"maybeMissing")) |
| 507 So(loaded.GetChild("mayb
eMissing").Object, ShouldHaveSameTypeAs, &EmptyObject{}) |
| 508 So(loaded.GetChild("mayb
eMissing").Object.ID(), ShouldResemble, mObjID) |
| 509 }) |
| 510 }) |
| 511 }) |
| 512 |
| 513 Convey("withBlobs", func() { |
| 514 Convey("missingErr (succeeds)", func() { |
| 515 loaded, err := LT(id, true, true
) |
| 516 So(err, ShouldBeNil) |
| 517 loaded.RawString() |
| 518 So(loaded.Complete(), ShouldBeTr
ue) |
| 519 So(loaded, ShouldResemble, tree) |
| 520 |
| 521 Convey("also works from a commit
object", func() { |
| 522 c, err := NewCommitFromR
aw([]byte(fmt.Sprintf(`tree %s |
| 523 author Jane Janerton <bob@chromium.org> 123456789 +0000 |
| 524 committer Bob Boberton <bob@chromium.org> 123456789 +0000 |
| 525 |
| 526 Super cool tree commit`, tree.ID()))) |
| 527 So(err, ShouldBeNil) |
| 528 s.Intern(c) |
| 529 cloaded, err := LT(c.ID(
), true, true) |
| 530 So(cloaded.Complete(), S
houldBeTrue) |
| 531 So(cloaded, ShouldResemb
le, loaded) |
| 532 |
| 533 }) |
| 534 |
| 535 Convey("removing a blob (maybeMi
ssing/blob)", func() { |
| 536 mObjID := tree.GetChild(
"maybeMissing/blob").Object.ID() |
| 537 delete(s, *mObjID) |
| 538 So(s.HasObjectID(mObjID)
, ShouldBeFalse) |
| 539 |
| 540 Convey("missingErr", fun
c() { |
| 541 _, err := LT(id,
true, true) |
| 542 So(err, ShouldNo
tBeNil) |
| 543 }) |
| 544 |
| 545 Convey("allowMissing", f
unc() { |
| 546 loaded, err := L
T(id, true, false) |
| 547 So(err, ShouldBe
Nil) |
| 548 So(loaded.GetChi
ld("maybeMissing/blob").Object, ShouldHaveSameTypeAs, &EmptyObject{}) |
| 549 So(loaded.GetChi
ld("maybeMissing/blob").Object.ID(), ShouldResemble, mObjID) |
| 550 }) |
| 551 |
| 552 }) |
| 553 }) |
| 554 }) |
| 555 }) |
| 556 }) |
| 557 }) |
| 558 } |
| OLD | NEW |