mirror of
https://github.com/lukaszraczylo/git-velocity.git
synced 2026-06-05 22:43:56 +00:00
324 lines
6.6 KiB
Go
324 lines
6.6 KiB
Go
package models
|
|
|
|
import (
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
)
|
|
|
|
func TestAuthor_DisplayName(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
tests := []struct {
|
|
name string
|
|
author Author
|
|
expected string
|
|
}{
|
|
{
|
|
name: "prefers name over login",
|
|
author: Author{Login: "johndoe", Name: "John Doe", Email: "john@example.com"},
|
|
expected: "John Doe",
|
|
},
|
|
{
|
|
name: "falls back to login",
|
|
author: Author{Login: "johndoe", Email: "john@example.com"},
|
|
expected: "johndoe",
|
|
},
|
|
{
|
|
name: "falls back to email",
|
|
author: Author{Email: "john@example.com"},
|
|
expected: "john@example.com",
|
|
},
|
|
{
|
|
name: "returns Unknown when empty",
|
|
author: Author{},
|
|
expected: "Unknown",
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
t.Parallel()
|
|
assert.Equal(t, tt.expected, tt.author.DisplayName())
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestPullRequest_IsMerged(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
now := time.Now()
|
|
|
|
tests := []struct {
|
|
name string
|
|
pr PullRequest
|
|
expected bool
|
|
}{
|
|
{
|
|
name: "merged state",
|
|
pr: PullRequest{State: PRStateMerged},
|
|
expected: true,
|
|
},
|
|
{
|
|
name: "has merged_at",
|
|
pr: PullRequest{State: PRStateClosed, MergedAt: &now},
|
|
expected: true,
|
|
},
|
|
{
|
|
name: "open PR",
|
|
pr: PullRequest{State: PRStateOpen},
|
|
expected: false,
|
|
},
|
|
{
|
|
name: "closed without merge",
|
|
pr: PullRequest{State: PRStateClosed},
|
|
expected: false,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
t.Parallel()
|
|
assert.Equal(t, tt.expected, tt.pr.IsMerged())
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestPullRequest_Size(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
tests := []struct {
|
|
name string
|
|
additions int
|
|
deletions int
|
|
expected PRSize
|
|
}{
|
|
{
|
|
name: "xs",
|
|
additions: 5,
|
|
deletions: 3,
|
|
expected: PRSizeXS,
|
|
},
|
|
{
|
|
name: "s",
|
|
additions: 30,
|
|
deletions: 15,
|
|
expected: PRSizeS,
|
|
},
|
|
{
|
|
name: "m",
|
|
additions: 100,
|
|
deletions: 50,
|
|
expected: PRSizeM,
|
|
},
|
|
{
|
|
name: "l",
|
|
additions: 300,
|
|
deletions: 100,
|
|
expected: PRSizeL,
|
|
},
|
|
{
|
|
name: "xl",
|
|
additions: 400,
|
|
deletions: 200,
|
|
expected: PRSizeXL,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
t.Parallel()
|
|
pr := PullRequest{Additions: tt.additions, Deletions: tt.deletions}
|
|
assert.Equal(t, tt.expected, pr.Size())
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestPullRequest_CalculateTimeToMerge(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
t.Run("returns duration when merged", func(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
created := time.Date(2024, 1, 1, 10, 0, 0, 0, time.UTC)
|
|
merged := time.Date(2024, 1, 1, 14, 0, 0, 0, time.UTC)
|
|
pr := PullRequest{CreatedAt: created, MergedAt: &merged}
|
|
|
|
result := pr.CalculateTimeToMerge()
|
|
assert.NotNil(t, result)
|
|
assert.Equal(t, 4*time.Hour, *result)
|
|
})
|
|
|
|
t.Run("returns nil when not merged", func(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
pr := PullRequest{CreatedAt: time.Now()}
|
|
assert.Nil(t, pr.CalculateTimeToMerge())
|
|
})
|
|
}
|
|
|
|
func TestPullRequest_CalculateTimeToFirstReview(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
t.Run("returns duration to first review", func(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
created := time.Date(2024, 1, 1, 10, 0, 0, 0, time.UTC)
|
|
review1 := time.Date(2024, 1, 1, 12, 0, 0, 0, time.UTC)
|
|
review2 := time.Date(2024, 1, 1, 14, 0, 0, 0, time.UTC)
|
|
|
|
pr := PullRequest{
|
|
CreatedAt: created,
|
|
Reviews: []Review{
|
|
{SubmittedAt: review2},
|
|
{SubmittedAt: review1}, // Earlier review
|
|
},
|
|
}
|
|
|
|
result := pr.CalculateTimeToFirstReview()
|
|
assert.NotNil(t, result)
|
|
assert.Equal(t, 2*time.Hour, *result)
|
|
})
|
|
|
|
t.Run("returns nil when no reviews", func(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
pr := PullRequest{CreatedAt: time.Now(), Reviews: []Review{}}
|
|
assert.Nil(t, pr.CalculateTimeToFirstReview())
|
|
})
|
|
}
|
|
|
|
func TestReview_IsApproval(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
tests := []struct {
|
|
name string
|
|
state ReviewState
|
|
expected bool
|
|
}{
|
|
{name: "approved", state: ReviewApproved, expected: true},
|
|
{name: "changes requested", state: ReviewChangesRequested, expected: false},
|
|
{name: "commented", state: ReviewCommented, expected: false},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
t.Parallel()
|
|
r := Review{State: tt.state}
|
|
assert.Equal(t, tt.expected, r.IsApproval())
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestReview_RequestsChanges(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
tests := []struct {
|
|
name string
|
|
state ReviewState
|
|
expected bool
|
|
}{
|
|
{name: "approved", state: ReviewApproved, expected: false},
|
|
{name: "changes requested", state: ReviewChangesRequested, expected: true},
|
|
{name: "commented", state: ReviewCommented, expected: false},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
t.Parallel()
|
|
r := Review{State: tt.state}
|
|
assert.Equal(t, tt.expected, r.RequestsChanges())
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestReview_IsSubstantive(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
tests := []struct {
|
|
name string
|
|
review Review
|
|
expected bool
|
|
}{
|
|
{
|
|
name: "has body",
|
|
review: Review{Body: "Good work!"},
|
|
expected: true,
|
|
},
|
|
{
|
|
name: "has comments",
|
|
review: Review{CommentsCount: 3},
|
|
expected: true,
|
|
},
|
|
{
|
|
name: "requests changes",
|
|
review: Review{State: ReviewChangesRequested},
|
|
expected: true,
|
|
},
|
|
{
|
|
name: "empty approval",
|
|
review: Review{State: ReviewApproved},
|
|
expected: false,
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
t.Parallel()
|
|
assert.Equal(t, tt.expected, tt.review.IsSubstantive())
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestIssue_IsClosed(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
tests := []struct {
|
|
name string
|
|
state IssueState
|
|
expected bool
|
|
}{
|
|
{name: "open", state: IssueStateOpen, expected: false},
|
|
{name: "closed", state: IssueStateClosed, expected: true},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
t.Parallel()
|
|
issue := Issue{State: tt.state}
|
|
assert.Equal(t, tt.expected, issue.IsClosed())
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestIssue_CalculateTimeToClose(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
t.Run("returns duration when closed", func(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
created := time.Date(2024, 1, 1, 10, 0, 0, 0, time.UTC)
|
|
closed := time.Date(2024, 1, 3, 10, 0, 0, 0, time.UTC)
|
|
issue := Issue{CreatedAt: created, ClosedAt: &closed}
|
|
|
|
result := issue.CalculateTimeToClose()
|
|
assert.NotNil(t, result)
|
|
assert.Equal(t, 48*time.Hour, *result)
|
|
})
|
|
|
|
t.Run("returns nil when not closed", func(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
issue := Issue{CreatedAt: time.Now()}
|
|
assert.Nil(t, issue.CalculateTimeToClose())
|
|
})
|
|
}
|
|
|
|
func TestPullRequest_TotalChanges(t *testing.T) {
|
|
t.Parallel()
|
|
|
|
pr := PullRequest{Additions: 200, Deletions: 100}
|
|
assert.Equal(t, 300, pr.TotalChanges())
|
|
}
|