summaryrefslogtreecommitdiff
path: root/git/test/objects/test_tree.py
blob: 6317f4db580be0415d1a532ed2513c1c7035218b (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
# test_tree.py
# Copyright (C) 2008, 2009 Michael Trier (mtrier@gmail.com) and contributors
#
# This module is part of GitPython and is released under
# the BSD License: http://www.opensource.org/licenses/bsd-license.php


from lib import *
from git.objects.fun import (
                                traverse_tree_recursive,
                                traverse_trees_recursive
                            )
from git.objects.blob import Blob
from git.objects.tree import Tree
from cStringIO import StringIO
import os

class TestTree(TestObjectBase):
    
    def test_serializable(self):
        # tree at the given commit contains a submodule as well
        roottree = self.rorepo.tree('6c1faef799095f3990e9970bc2cb10aa0221cf9c')
        for item in roottree.traverse(ignore_self=False):
            if item.type != Tree.type:
                continue
            # END skip non-trees
            tree = item
            # trees have no dict
            self.failUnlessRaises(AttributeError, setattr, tree, 'someattr', 1)
            
            orig_data = tree.data_stream.read()
            orig_cache = tree._cache
            
            stream = StringIO()
            tree._serialize(stream)
            assert stream.getvalue() == orig_data
            
            stream.seek(0)
            testtree = Tree(self.rorepo, Tree.NULL_BIN_SHA, 0, '')
            testtree._deserialize(stream)
            assert testtree._cache == orig_cache
            
            
            # TEST CACHE MUTATOR
            mod = testtree.cache
            self.failUnlessRaises(ValueError, mod.add, "invalid sha", 0, "name")
            self.failUnlessRaises(ValueError, mod.add, Tree.NULL_HEX_SHA, 0, "invalid mode")
            self.failUnlessRaises(ValueError, mod.add, Tree.NULL_HEX_SHA, tree.mode, "invalid/name")
            
            # add new item
            name = "fake_dir"
            mod.add(testtree.NULL_HEX_SHA, tree.mode, name)
            assert name in testtree
            
            # its available in the tree immediately
            assert isinstance(testtree[name], Tree)
            
            # adding it again will not cause multiple of them to be presents
            cur_count = len(testtree)
            mod.add(testtree.NULL_HEX_SHA, tree.mode, name)
            assert len(testtree) == cur_count
            
            # fails with a different sha - name exists
            hexsha = "1"*40
            self.failUnlessRaises(ValueError, mod.add, hexsha, tree.mode, name)
            
            # force it - replace existing one
            mod.add(hexsha, tree.mode, name, force=True)
            assert testtree[name].hexsha == hexsha
            assert len(testtree) == cur_count
            
            # unchecked addition always works, even with invalid items
            invalid_name = "hi/there"
            mod.add_unchecked(hexsha, 0, invalid_name)
            assert len(testtree) == cur_count + 1
            
            del(mod[invalid_name])
            assert len(testtree) == cur_count
            # del again, its fine
            del(mod[invalid_name])
            
            # have added one item, we are done
            mod.set_done()
            mod.set_done()      # multiple times are okay
            
            # serialize, its different now
            stream = StringIO()
            testtree._serialize(stream)
            stream.seek(0)
            assert stream.getvalue() != orig_data
            
            # replaces cache, but we make sure of it
            del(testtree._cache)
            testtree._deserialize(stream)
            assert name in testtree
            assert invalid_name not in testtree
        # END for each item in tree
    
    def test_traverse(self):
        root = self.rorepo.tree('0.1.6')
        num_recursive = 0
        all_items = list()
        for obj in root.traverse():
            if "/" in obj.path:
                num_recursive += 1
                
            assert isinstance(obj, (Blob, Tree))
            all_items.append(obj)
        # END for each object
        assert all_items == root.list_traverse()
        
        # limit recursion level to 0 - should be same as default iteration
        assert all_items
        assert 'CHANGES' in root
        assert len(list(root)) == len(list(root.traverse(depth=1)))
        
        # only choose trees
        trees_only = lambda i,d: i.type == "tree"
        trees = list(root.traverse(predicate = trees_only))
        assert len(trees) == len(list( i for i in root.traverse() if trees_only(i,0) ))
        
        # test prune
        lib_folder = lambda t,d: t.path == "lib"
        pruned_trees = list(root.traverse(predicate = trees_only,prune = lib_folder))
        assert len(pruned_trees) < len(trees)
        
        # trees and blobs
        assert len(set(trees)|set(root.trees)) == len(trees)
        assert len(set(b for b in root if isinstance(b, Blob)) | set(root.blobs)) == len( root.blobs )
        subitem = trees[0][0]
        assert "/" in subitem.path
        assert subitem.name == os.path.basename(subitem.path)
        
        # assure that at some point the traversed paths have a slash in them
        found_slash = False
        for item in root.traverse():
            assert os.path.isabs(item.abspath)
            if '/' in item.path:
                found_slash = True
            # END check for slash
            
            # slashes in paths are supported as well 
            assert root[item.path] == item == root/item.path
        # END for each item
        assert found_slash