Fix for infinite loop bug in blame.
[catagits/Gitalist.git] / t / 02git_object.t
1 use FindBin qw/$Bin/;
2 BEGIN {
3     my $env = "$FindBin::Bin/../script/env";
4     if (-r $env) {
5         do $env or die $@;
6     }
7 }
8
9 use strict;
10 use warnings;
11 use Test::More;
12 use Test::Exception;
13 use Data::Dumper;
14 use Test::Deep;
15
16 use Path::Class;
17 use Gitalist::Git::Repository;
18 my $repository = Gitalist::Git::Repository->new(
19     dir("$Bin/lib/repositories/repo1"),
20 );
21
22 BEGIN {
23     use_ok 'Gitalist::Git::Object::Tree';
24     use_ok 'Gitalist::Git::Object::Blob';
25     use_ok 'Gitalist::Git::Object::Commit';
26     use_ok 'Gitalist::Git::Object::Tag';
27 }
28
29 my $object = Gitalist::Git::Object::Tree->new(
30     repository => $repository,
31     sha1 => '729a7c3f6ba5453b42d16a43692205f67fb23bc1',
32     type => 'tree',
33     file => 'dir1',
34     mode => 16384,
35 );
36 isa_ok($object, 'Gitalist::Git::Object::Tree', 'tree object');
37 is($object->sha1,'729a7c3f6ba5453b42d16a43692205f67fb23bc1', 'sha1 is correct');
38 is($object->type, 'tree', 'type is correct');
39 is($object->file, 'dir1', 'file is correct');
40 is($object->mode, 16384, 'mode is correct');
41 is($object->modestr, 'drwxr-xr-x', "modestr is correct" );
42 is($object->size, 33, "size is correct");
43 is($object,'729a7c3f6ba5453b42d16a43692205f67fb23bc1', 'stringifies correctly');
44
45 cmp_deeply $object->pack, {
46     __CLASS__
47          => 'Gitalist::Git::Object::Tree',
48     file   => 'dir1',
49     mode   => 16384,
50     modestr
51          => 'drwxr-xr-x',
52     repository
53          => {
54              __CLASS__   => 'Gitalist::Git::Repository',
55              description => 'some test repository',
56              is_bare     => 1,
57              last_change => '2011-06-05T23:00:44Z',
58              name        => 'repo1',
59              owner       => code(\&is_system_account_name),
60          },
61     sha1   => '729a7c3f6ba5453b42d16a43692205f67fb23bc1',
62     size   => 33,
63     type   => 'tree'
64 }, 'Serialized tree correctly';
65
66 # Create object from sha1.
67 my $obj2 = Gitalist::Git::Object::Blob->new(
68     repository => $repository,
69     sha1 => '5716ca5987cbf97d6bb54920bea6adde242d87e6',
70 );
71 isa_ok($obj2, 'Gitalist::Git::Object::Blob', 'blob object');
72 is($obj2->sha1,'5716ca5987cbf97d6bb54920bea6adde242d87e6', 'sha1 is correct');
73 is($obj2->type, 'blob', 'type is correct');
74 is($obj2->mode, 0, 'mode is correct');
75 is($obj2->modestr, '----------', "modestr is correct" );
76 is($obj2->content, "bar\n", 'obj2 contents is correct');
77 is($obj2->size, 4, "size is correct");
78 dies_ok {
79     print $obj2->tree_sha1;
80 } 'tree_sha1 on a blob is an exception';
81 dies_ok {
82     print $obj2->comment;
83 } 'comment is an empty string';
84
85 cmp_deeply $obj2->pack,  {
86     __CLASS__
87          => 'Gitalist::Git::Object::Blob',
88     mode   => 0,
89     modestr
90          => '----------',
91     repository
92          => {
93              __CLASS__   => 'Gitalist::Git::Repository',
94              description => 'some test repository',
95              is_bare     => 1,
96              last_change => '2011-06-05T23:00:44Z',
97              name        => 'repo1',
98              owner       => code(\&is_system_account_name),
99          },
100     sha1   => '5716ca5987cbf97d6bb54920bea6adde242d87e6',
101     size   => 4,
102     type   => 'blob'
103 }, 'Serialized blob correctly';
104
105 my $commit_obj = Gitalist::Git::Object::Commit->new(
106     repository => $repository,
107     sha1 => '3f7567c7bdf7e7ebf410926493b92d398333116e',
108 );
109 isa_ok($commit_obj, 'Gitalist::Git::Object::Commit', "commit object");
110 isa_ok($commit_obj->tree->[0], 'Gitalist::Git::Object::Tree');
111
112 cmp_deeply $commit_obj->pack,  {
113     __CLASS__
114          => 'Gitalist::Git::Object::Commit',
115     mode   => 0,
116     modestr
117          => '----------',
118     repository
119          => {
120              __CLASS__   => 'Gitalist::Git::Repository',
121              description => 'some test repository',
122              is_bare     => 1,
123              last_change => '2011-06-05T23:00:44Z',
124              name        => 'repo1',
125              owner       => code(\&is_system_account_name),
126          },
127     sha1   => '3f7567c7bdf7e7ebf410926493b92d398333116e',
128     size   => 218,
129     tree   => [ {
130         __CLASS__
131              => 'Gitalist::Git::Object::Tree',
132         mode   => 0,
133         modestr
134              => '----------',
135         repository
136              => {
137                  __CLASS__   => 'Gitalist::Git::Repository',
138                  description => 'some test repository',
139                  is_bare     => 1,
140                  last_change => '2011-06-05T23:00:44Z',
141                  name        => 'repo1',
142                  owner       => code(\&is_system_account_name),
143              },
144         sha1   => '9062594aebb5df0de7fb92413f17a9eced196c22',
145         size   => 33,
146         type   => 'tree'
147     } ],
148     type   => 'commit'
149 }, 'Serialized commit correctly';
150
151 my ($tree, $patch) = $commit_obj->diff(
152     patch => 1,
153 );
154 $patch = $patch->[0];
155 is($patch->{head}, 'diff --git a/file1 b/file1', 'patch->{head} is correct');
156 is($patch->{a}, 'a/file1', 'patch->{a} is correct');
157 is($patch->{b}, 'b/file1', 'patch->{b} is correct');
158 is($patch->{file}, 'file1', 'patch->{file} is correct');
159 is($patch->{mode}, '100644', 'patch->{mode} is correct');
160 is($patch->{src}, '257cc5642cb1a054f08cc83f2d943e56fd3ebe99', 'patch->{src} is correct');
161 is($patch->{index}, 'index 257cc5642cb1a054f08cc83f2d943e56fd3ebe99..5716ca5987cbf97d6bb54920bea6adde242d87e6 100644', 'patch->{index} is correct');
162 is($patch->{diff}, '--- a/file1
163 +++ b/file1
164 @@ -1 +1 @@
165 -foo
166 +bar
167 ', 'patch->{diff} is correct');
168 is($patch->{dst}, '5716ca5987cbf97d6bb54920bea6adde242d87e6', 'patch->{dst} is correct');
169
170 {
171     my $contents = do { local $/; my $fh = $commit_obj->get_patch; <$fh> };
172 ok(index($contents,
173 'From 3f7567c7bdf7e7ebf410926493b92d398333116e Mon Sep 17 00:00:00 2001
174 From: Florian Ragwitz <rafl@debian.org>
175 Date: Tue, 6 Mar 2007 20:39:45 +0100
176 Subject: [PATCH] bar
177
178 ---
179  file1 |    2 +-
180  1 files changed, 1 insertions(+), 1 deletions(-)
181
182 diff --git a/file1 b/file1
183 index 257cc56..5716ca5 100644
184 --- a/file1
185 +++ b/file1
186 @@ -1 +1 @@
187 -foo
188 +bar
189 --') == 0, 'commit_obj->get_patch can return a patch')
190     or warn("Got instead: $contents");
191 }
192
193 # Note - 2 patches = 3 parts due to where we split.
194 {
195     my $contents = do { local $/; my $fh = $commit_obj->get_patch(undef, 3); <$fh> };
196     my @bits = split /Subject: \[PATC/, $contents;
197     is(scalar(@bits), 3,
198         'commit_obj->get_patch can return a patchset')
199         or warn("Contents was $contents");
200 }
201
202 my $blame_this = Gitalist::Git::Object::Commit->new(
203     repository => $repository,
204     sha1       => 'd6ddf8b26be63066e01d96a0922c87cd8d6e2270',
205 );
206
207 {
208     local $SIG{ALRM} = sub { die "Regressions suck!" };
209     alarm 1;
210     eval { $blame_this->blame('empty-for-a-reason', $blame_this->sha1) };
211     is $@, '', "Silly infinite loop didn't manifest for an empty file.";
212 }
213
214 done_testing;
215
216 sub is_system_account_name {
217     my $name = shift;
218     return 0 if !$name;
219     return 1;
220 }