Line 0
Link Here
|
0 |
- |
1 |
#!/usr/bin/perl |
|
|
2 |
|
3 |
use Modern::Perl; |
4 |
use Test::More; |
5 |
use FindBin; |
6 |
use lib "$FindBin::Bin/../lib"; |
7 |
|
8 |
=head1 NAME |
9 |
|
10 |
t/attach_order.t - Test that attachments are uploaded in correct chronological order |
11 |
|
12 |
=head1 DESCRIPTION |
13 |
|
14 |
Tests that when attaching multiple commits, they are uploaded in chronological |
15 |
order (oldest first) so they can be applied correctly later. |
16 |
|
17 |
=cut |
18 |
|
19 |
# Simple mock for testing without external dependencies |
20 |
{ |
21 |
package MockBug; |
22 |
sub new { |
23 |
my ($class, %args) = @_; |
24 |
bless { %args, _attachments => [] }, $class; |
25 |
} |
26 |
sub id { $_[0]->{id} } |
27 |
sub summary { $_[0]->{summary} } |
28 |
sub status { $_[0]->{status} } |
29 |
sub attachments { $_[0]->{_attachments} } |
30 |
sub add_attachment { |
31 |
my ($self, $patch, $filename, $description, %opts) = @_; |
32 |
push @{$self->{_attachment_order}}, $description; |
33 |
return 1; |
34 |
} |
35 |
} |
36 |
|
37 |
{ |
38 |
package MockCommands; |
39 |
sub new { |
40 |
my ($class, %args) = @_; |
41 |
bless \%args, $class; |
42 |
} |
43 |
} |
44 |
|
45 |
subtest 'current behavior - attachments uploaded in reverse chronological order' => sub { |
46 |
plan tests => 4; |
47 |
|
48 |
# Track attachment order |
49 |
my @attachment_order; |
50 |
|
51 |
# Create mock bug that captures attachment order |
52 |
my $bug = MockBug->new( |
53 |
id => 12345, |
54 |
summary => 'Test bug', |
55 |
status => 'NEW', |
56 |
_attachment_order => \@attachment_order |
57 |
); |
58 |
|
59 |
# Simulate current GitBz::Git->get_commits behavior (reverse chronological) |
60 |
my @commits = ( |
61 |
{ id => 'abc123', subject => 'Third commit (newest)' }, |
62 |
{ id => 'def456', subject => 'Second commit (middle)' }, |
63 |
{ id => 'ghi789', subject => 'First commit (oldest)' }, |
64 |
); |
65 |
|
66 |
# Simulate current attach_patches behavior |
67 |
for my $commit (@commits) { |
68 |
$bug->add_attachment( |
69 |
"patch content", |
70 |
$commit->{id} . ".patch", |
71 |
$commit->{subject} |
72 |
); |
73 |
} |
74 |
|
75 |
# Verify current (wrong) behavior |
76 |
is(scalar @attachment_order, 3, 'Three attachments were created'); |
77 |
is($attachment_order[0], 'Third commit (newest)', 'First attachment is newest commit (WRONG)'); |
78 |
is($attachment_order[1], 'Second commit (middle)', 'Second attachment is middle commit'); |
79 |
is($attachment_order[2], 'First commit (oldest)', 'Third attachment is oldest commit (WRONG)'); |
80 |
|
81 |
note("CURRENT BEHAVIOR (BROKEN): " . join(' -> ', @attachment_order)); |
82 |
note("This is backwards! Patches should be applied oldest-first for correct git apply sequence."); |
83 |
}; |
84 |
|
85 |
subtest 'expected correct behavior - chronological order' => sub { |
86 |
plan tests => 4; |
87 |
|
88 |
my @attachment_order; |
89 |
my $bug = MockBug->new( |
90 |
id => 12345, |
91 |
summary => 'Test bug', |
92 |
status => 'NEW', |
93 |
_attachment_order => \@attachment_order |
94 |
); |
95 |
|
96 |
# What the corrected behavior should return (chronological order) |
97 |
my @commits = ( |
98 |
{ id => 'ghi789', subject => 'First commit (oldest)' }, |
99 |
{ id => 'def456', subject => 'Second commit (middle)' }, |
100 |
{ id => 'abc123', subject => 'Third commit (newest)' }, |
101 |
); |
102 |
|
103 |
# Simulate corrected attach_patches behavior |
104 |
for my $commit (@commits) { |
105 |
$bug->add_attachment( |
106 |
"patch content", |
107 |
$commit->{id} . ".patch", |
108 |
$commit->{subject} |
109 |
); |
110 |
} |
111 |
|
112 |
# Verify correct behavior |
113 |
is(scalar @attachment_order, 3, 'Three attachments were created'); |
114 |
is($attachment_order[0], 'First commit (oldest)', 'First attachment is oldest commit (CORRECT)'); |
115 |
is($attachment_order[1], 'Second commit (middle)', 'Second attachment is middle commit'); |
116 |
is($attachment_order[2], 'Third commit (newest)', 'Third attachment is newest commit (CORRECT)'); |
117 |
|
118 |
note("EXPECTED BEHAVIOR (CORRECT): " . join(' -> ', @attachment_order)); |
119 |
note("This is the correct order for sequential git apply."); |
120 |
}; |
121 |
|
122 |
subtest 'git rev-list default behavior analysis' => sub { |
123 |
plan tests => 1; |
124 |
|
125 |
# Document the root cause: git rev-list returns newest-first by default |
126 |
my $explanation = <<'EOF'; |
127 |
ROOT CAUSE ANALYSIS: |
128 |
- git rev-list returns commits in reverse chronological order (newest first) |
129 |
- GitBz::Git->get_commits() uses git rev-list without --reverse flag |
130 |
- attach_patches() processes commits in the order returned by get_commits() |
131 |
- Result: attachments are uploaded newest-first (backwards for applying) |
132 |
|
133 |
SOLUTION: |
134 |
- Add --reverse flag to git rev-list in GitBz::Git->rev_list() |
135 |
- This will return commits in chronological order (oldest first) |
136 |
- Attachments will then be uploaded in correct sequence for git apply |
137 |
EOF |
138 |
|
139 |
pass("Analysis documented"); |
140 |
note($explanation); |
141 |
}; |
142 |
|
143 |
done_testing(); |