1# Copyright 2010-2021 The pygit2 contributors
2#
3# This file is free software; you can redistribute it and/or modify
4# it under the terms of the GNU General Public License, version 2,
5# as published by the Free Software Foundation.
6#
7# In addition to the permissions in the GNU General Public License,
8# the authors give you unlimited permission to link the compiled
9# version of this file into combinations with other programs,
10# and to distribute those combinations without any restriction
11# coming from the use of this file.  (The General Public License
12# restrictions do apply in other respects; for example, they cover
13# modification of the file, and distribution when not linked into
14# a combined executable.)
15#
16# This file is distributed in the hope that it will be useful, but
17# WITHOUT ANY WARRANTY; without even the implied warranty of
18# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
19# General Public License for more details.
20#
21# You should have received a copy of the GNU General Public License
22# along with this program; see the file COPYING.  If not, write to
23# the Free Software Foundation, 51 Franklin Street, Fifth Floor,
24# Boston, MA 02110-1301, USA.
25
26"""Tests for Object objects."""
27
28import pytest
29
30from pygit2 import GIT_OBJ_TREE, GIT_OBJ_TAG, Tree, Tag
31
32
33BLOB_SHA = 'a520c24d85fbfc815d385957eed41406ca5a860b'
34BLOB_CONTENT = """hello world
35hola mundo
36bonjour le monde
37""".encode()
38BLOB_NEW_CONTENT = b'foo bar\n'
39BLOB_FILE_CONTENT = b'bye world\n'
40
41
42def test_equality(testrepo):
43    # get a commit object twice and see if it equals ittestrepo
44    commit_id = testrepo.lookup_reference('refs/heads/master').target
45    commit_a = testrepo[commit_id]
46    commit_b = testrepo[commit_id]
47
48    assert commit_a is not commit_b
49    assert commit_a == commit_b
50    assert not(commit_a != commit_b)
51
52def test_hashing(testrepo):
53    # get a commit object twice and compare hashes
54    commit_id = testrepo.lookup_reference('refs/heads/master').target
55    commit_a = testrepo[commit_id]
56    commit_b = testrepo[commit_id]
57
58    assert hash(commit_a)
59
60    assert commit_a is not commit_b
61    assert commit_a == commit_b
62    # if the commits are equal then their hash *must* be equal
63    # but different objects can have the same commit
64    assert hash(commit_a) == hash(commit_b)
65
66    # sanity check that python container types work as expected
67    s = set()
68    s.add(commit_a)
69    s.add(commit_b)
70    assert len(s) == 1
71    assert commit_a in s
72    assert commit_b in s
73
74    d = {}
75    d[commit_a] = True
76    assert commit_b in d
77    assert d[commit_b]
78
79    l = [commit_a]
80    assert commit_b in l
81
82def test_peel_commit(testrepo):
83    # start by looking up the commit
84    commit_id = testrepo.lookup_reference('refs/heads/master').target
85    commit = testrepo[commit_id]
86    # and peel to the tree
87    tree = commit.peel(GIT_OBJ_TREE)
88
89    assert type(tree) == Tree
90    assert str(tree.id) == 'fd937514cb799514d4b81bb24c5fcfeb6472b245'
91
92def test_peel_commit_type(testrepo):
93    commit_id = testrepo.lookup_reference('refs/heads/master').target
94    commit = testrepo[commit_id]
95    tree = commit.peel(Tree)
96
97    assert type(tree) == Tree
98    assert str(tree.id) == 'fd937514cb799514d4b81bb24c5fcfeb6472b245'
99
100
101def test_invalid(testrepo):
102    commit_id = testrepo.lookup_reference('refs/heads/master').target
103    commit = testrepo[commit_id]
104
105    with pytest.raises(ValueError): commit.peel(GIT_OBJ_TAG)
106
107def test_invalid_type(testrepo):
108    commit_id = testrepo.lookup_reference('refs/heads/master').target
109    commit = testrepo[commit_id]
110
111    with pytest.raises(ValueError): commit.peel(Tag)
112
113def test_short_id(testrepo):
114    seen = {} # from short_id to full hex id
115    def test_obj(obj, msg):
116        short_id = obj.short_id
117        msg = msg+" short_id="+short_id
118        already = seen.get(short_id)
119        if already:
120            assert already == obj.id.hex
121        else:
122            seen[short_id] = obj.id.hex
123            lookup = testrepo[short_id]
124            assert obj.id == lookup.id
125    for commit in testrepo.walk(testrepo.head.target):
126        test_obj(commit, "commit#"+commit.id.hex)
127        tree = commit.tree
128        test_obj(tree, "tree#"+tree.id.hex)
129        for entry in tree:
130            test_obj(testrepo[entry.hex], "entry="+entry.name+"#"+entry.hex)
131
132
133def test_repr(testrepo):
134    commit_id = testrepo.lookup_reference('refs/heads/master').target
135    commit_a = testrepo[commit_id]
136    assert repr(commit_a) == "<pygit2.Object{commit:%s}>" % commit_id
137