2016-12-29 02:44:32 +03:00
// Copyright 2016 The Gitea Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
2019-11-16 03:47:57 +03:00
package gitgraph
2016-12-29 02:44:32 +03:00
import (
2020-08-06 11:04:08 +03:00
"bytes"
2018-07-21 21:17:10 +03:00
"fmt"
2020-08-06 11:04:08 +03:00
"strings"
2016-12-29 02:44:32 +03:00
"testing"
2019-03-27 12:33:00 +03:00
"code.gitea.io/gitea/modules/git"
2016-12-29 02:44:32 +03:00
)
func BenchmarkGetCommitGraph ( b * testing . B ) {
currentRepo , err := git . OpenRepository ( "." )
2020-08-06 11:04:08 +03:00
if err != nil || currentRepo == nil {
2016-12-29 02:44:32 +03:00
b . Error ( "Could not open repository" )
}
2019-11-13 10:01:19 +03:00
defer currentRepo . Close ( )
2016-12-29 02:44:32 +03:00
2017-01-03 05:52:09 +03:00
for i := 0 ; i < b . N ; i ++ {
2020-08-06 11:04:08 +03:00
graph , err := GetCommitGraph ( currentRepo , 1 , 0 )
2017-01-03 05:52:09 +03:00
if err != nil {
b . Error ( "Could get commit graph" )
}
2020-08-06 11:04:08 +03:00
if len ( graph . Commits ) < 100 {
2017-01-03 05:52:09 +03:00
b . Error ( "Should get 100 log lines." )
}
2016-12-29 02:44:32 +03:00
}
}
func BenchmarkParseCommitString ( b * testing . B ) {
2020-08-06 11:04:08 +03:00
testString := "* DATA:|4e61bacab44e9b4730e44a6615d04098dd3a8eaf|2016-12-20 21:10:41 +0100|Kjell Kvinge|kjell@kvinge.biz|4e61bac|Add route for graph"
2016-12-29 02:44:32 +03:00
2020-08-06 11:04:08 +03:00
parser := & Parser { }
parser . Reset ( )
2017-01-03 05:52:09 +03:00
for i := 0 ; i < b . N ; i ++ {
2020-08-06 11:04:08 +03:00
parser . Reset ( )
graph := NewGraph ( )
if err := parser . AddLineToGraph ( graph , 0 , [ ] byte ( testString ) ) ; err != nil {
2017-01-03 05:52:09 +03:00
b . Error ( "could not parse teststring" )
}
2020-08-06 11:04:08 +03:00
if graph . Flows [ 1 ] . Commits [ 0 ] . Author != "Kjell Kvinge" {
2017-01-03 05:52:09 +03:00
b . Error ( "Did not get expected data" )
}
2016-12-29 02:44:32 +03:00
}
}
2018-07-21 21:17:10 +03:00
2020-08-06 11:04:08 +03:00
func BenchmarkParseGlyphs ( b * testing . B ) {
parser := & Parser { }
parser . Reset ( )
tgBytes := [ ] byte ( testglyphs )
tg := tgBytes
idx := bytes . Index ( tg , [ ] byte ( "\n" ) )
for i := 0 ; i < b . N ; i ++ {
parser . Reset ( )
tg = tgBytes
idx = bytes . Index ( tg , [ ] byte ( "\n" ) )
for idx > 0 {
parser . ParseGlyphs ( tg [ : idx ] )
tg = tg [ idx + 1 : ]
idx = bytes . Index ( tg , [ ] byte ( "\n" ) )
}
}
}
func TestReleaseUnusedColors ( t * testing . T ) {
testcases := [ ] struct {
availableColors [ ] int
oldColors [ ] int
firstInUse int // these values have to be either be correct or suggest less is
firstAvailable int // available than possibly is - i.e. you cannot say 10 is available when it
} {
{
availableColors : [ ] int { 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 } ,
oldColors : [ ] int { 1 , 1 , 1 , 1 , 1 } ,
firstAvailable : - 1 ,
firstInUse : 1 ,
} ,
{
availableColors : [ ] int { 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 } ,
oldColors : [ ] int { 1 , 2 , 3 , 4 } ,
firstAvailable : 6 ,
firstInUse : 0 ,
} ,
{
availableColors : [ ] int { 1 , 2 , 3 , 4 , 5 , 6 , 7 , 8 , 9 , 10 } ,
oldColors : [ ] int { 6 , 0 , 3 , 5 , 3 , 4 , 0 , 0 } ,
firstAvailable : 6 ,
firstInUse : 0 ,
} ,
{
availableColors : [ ] int { 1 , 2 , 3 , 4 , 5 , 6 , 7 } ,
oldColors : [ ] int { 6 , 1 , 3 , 5 , 3 , 4 , 2 , 7 } ,
firstAvailable : - 1 ,
firstInUse : 0 ,
} ,
{
availableColors : [ ] int { 1 , 2 , 3 , 4 , 5 , 6 , 7 } ,
oldColors : [ ] int { 6 , 0 , 3 , 5 , 3 , 4 , 2 , 7 } ,
firstAvailable : - 1 ,
firstInUse : 0 ,
} ,
}
for _ , testcase := range testcases {
parser := & Parser { }
parser . Reset ( )
parser . availableColors = append ( [ ] int { } , testcase . availableColors ... )
parser . oldColors = append ( parser . oldColors , testcase . oldColors ... )
parser . firstAvailable = testcase . firstAvailable
parser . firstInUse = testcase . firstInUse
parser . releaseUnusedColors ( )
if parser . firstAvailable == - 1 {
// All in use
for _ , color := range parser . availableColors {
found := false
for _ , oldColor := range parser . oldColors {
if oldColor == color {
found = true
break
}
}
if ! found {
t . Errorf ( "In testcase:\n%d\t%d\t%d %d =>\n%d\t%d\t%d %d: %d should be available but is not" ,
testcase . availableColors ,
testcase . oldColors ,
testcase . firstAvailable ,
testcase . firstInUse ,
parser . availableColors ,
parser . oldColors ,
parser . firstAvailable ,
parser . firstInUse ,
color )
}
}
} else if parser . firstInUse != - 1 {
// Some in use
for i := parser . firstInUse ; i != parser . firstAvailable ; i = ( i + 1 ) % len ( parser . availableColors ) {
color := parser . availableColors [ i ]
found := false
for _ , oldColor := range parser . oldColors {
if oldColor == color {
found = true
break
}
}
if ! found {
t . Errorf ( "In testcase:\n%d\t%d\t%d %d =>\n%d\t%d\t%d %d: %d should be available but is not" ,
testcase . availableColors ,
testcase . oldColors ,
testcase . firstAvailable ,
testcase . firstInUse ,
parser . availableColors ,
parser . oldColors ,
parser . firstAvailable ,
parser . firstInUse ,
color )
}
}
for i := parser . firstAvailable ; i != parser . firstInUse ; i = ( i + 1 ) % len ( parser . availableColors ) {
color := parser . availableColors [ i ]
found := false
for _ , oldColor := range parser . oldColors {
if oldColor == color {
found = true
break
}
}
if found {
t . Errorf ( "In testcase:\n%d\t%d\t%d %d =>\n%d\t%d\t%d %d: %d should not be available but is" ,
testcase . availableColors ,
testcase . oldColors ,
testcase . firstAvailable ,
testcase . firstInUse ,
parser . availableColors ,
parser . oldColors ,
parser . firstAvailable ,
parser . firstInUse ,
color )
}
}
} else {
// None in use
for _ , color := range parser . oldColors {
if color != 0 {
t . Errorf ( "In testcase:\n%d\t%d\t%d %d =>\n%d\t%d\t%d %d: %d should not be available but is" ,
testcase . availableColors ,
testcase . oldColors ,
testcase . firstAvailable ,
testcase . firstInUse ,
parser . availableColors ,
parser . oldColors ,
parser . firstAvailable ,
parser . firstInUse ,
color )
}
}
}
}
}
func TestParseGlyphs ( t * testing . T ) {
parser := & Parser { }
parser . Reset ( )
tgBytes := [ ] byte ( testglyphs )
tg := tgBytes
idx := bytes . Index ( tg , [ ] byte ( "\n" ) )
row := 0
for idx > 0 {
parser . ParseGlyphs ( tg [ : idx ] )
tg = tg [ idx + 1 : ]
idx = bytes . Index ( tg , [ ] byte ( "\n" ) )
if parser . flows [ 0 ] != 1 {
t . Errorf ( "First column flow should be 1 but was %d" , parser . flows [ 0 ] )
}
colorToFlow := map [ int ] int64 { }
flowToColor := map [ int64 ] int { }
for i , flow := range parser . flows {
if flow == 0 {
continue
}
color := parser . colors [ i ]
if fColor , in := flowToColor [ flow ] ; in && fColor != color {
t . Errorf ( "Row %d column %d flow %d has color %d but should be %d" , row , i , flow , color , fColor )
}
flowToColor [ flow ] = color
if cFlow , in := colorToFlow [ color ] ; in && cFlow != flow {
t . Errorf ( "Row %d column %d flow %d has color %d but conflicts with flow %d" , row , i , flow , color , cFlow )
}
colorToFlow [ color ] = flow
}
row ++
}
if len ( parser . availableColors ) != 9 {
t . Errorf ( "Expected 9 colors but have %d" , len ( parser . availableColors ) )
}
}
2018-07-21 21:17:10 +03:00
func TestCommitStringParsing ( t * testing . T ) {
2020-08-06 11:04:08 +03:00
dataFirstPart := "* DATA:|4e61bacab44e9b4730e44a6615d04098dd3a8eaf|2016-12-20 21:10:41 +0100|Author|user@mail.something|4e61bac|"
2018-07-21 21:17:10 +03:00
tests := [ ] struct {
shouldPass bool
testName string
commitMessage string
} {
{ true , "normal" , "not a fancy message" } ,
{ true , "extra pipe" , "An extra pipe: |" } ,
{ true , "extra 'Data:'" , "DATA: might be trouble" } ,
}
for _ , test := range tests {
t . Run ( test . testName , func ( t * testing . T ) {
testString := fmt . Sprintf ( "%s%s" , dataFirstPart , test . commitMessage )
2020-08-06 11:04:08 +03:00
idx := strings . Index ( testString , "DATA:" )
commit , err := NewCommit ( 0 , 0 , [ ] byte ( testString [ idx + 5 : ] ) )
2018-07-21 21:17:10 +03:00
if err != nil && test . shouldPass {
t . Errorf ( "Could not parse %s" , testString )
return
}
2020-08-06 11:04:08 +03:00
if test . commitMessage != commit . Subject {
t . Errorf ( "%s does not match %s" , test . commitMessage , commit . Subject )
2018-07-21 21:17:10 +03:00
}
} )
}
}
2020-08-06 11:04:08 +03:00
var testglyphs = ` *
*
*
*
*
*
*
*
| \
* |
* |
* |
* |
* |
| *
* |
| *
| | \
* | |
| | *
| | | \
* | | \
| \ \ \ \
| * | | |
| | \ | | |
* | | | |
| / / / /
| | | *
| * | |
| * | |
| * | |
* | | |
* | | |
* | | |
* | | |
* | | |
| \ \ \ \
| | * | |
| | | \ | |
| | | * |
| | | | *
* | | | |
* | | | |
* | | | |
* | | | |
* | | | |
| \ \ \ \ \
| * | | | |
| / | | | | |
| | | / / /
| | / | | |
| | | | *
| * | | |
| / | | | |
| * | | |
| / | | | |
| | | / /
| | / | |
| * | |
| * | |
| | \ \ \
| | * | |
| | / | | |
| | | | /
| | | / |
| * | |
| * | |
| * | |
| | * |
| | | \ \
| | | * |
| | | / | |
| | | * |
| | | | \ \
| | | | * |
| | | | / | |
| | * | | |
| | * | | |
| | | \ \ \ \
| | | * | | |
| | | / | | | |
| | | | | * |
| | | | | / /
* | | | / /
| / / / / /
* | | | |
| \ \ \ \ \
| * | | | |
| / | | | | |
| * | | | |
| * | | | |
| | \ \ \ \ \
| | | * \ \ \
| | | | \ \ \ \
| | | | * | | |
| | | | / | | | |
| | | | | | / /
| | | | | / | |
* | | | | | |
* | | | | | |
* | | | | | |
| | | | * | |
* | | | | | |
| | * | | | |
| | / | | | | |
* | | | | | |
| | / / / / /
| / | | | | |
| | | | * |
| | | | / /
| | | / | |
| * | | |
| | | | *
| | * | |
| | | \ \ \
| | | * | |
| | | / | | |
| | | | / /
| | | * |
| | * | |
| | | \ \ \
| | | * | |
| | | / | | |
| | | | / /
| | | * |
* | | | |
| \ \ \ \ \
| * \ \ \ \
| | \ \ \ \ \
| | | | / / /
| | | / | | |
| | | | * |
| | | | * |
* | | | | |
* | | | | |
| / / / / /
| | | * |
* | | | |
* | | | |
* | | | |
* | | | |
| \ \ \ \ \
| * | | | |
| / | | | | |
| | * | | |
| | | \ \ \ \
| | | * | | |
| | | / | | | |
| | / | | | / /
| | | | / | |
| | | | | *
| | _ | _ | _ | /
| / | | | |
| | * | |
| | / / /
* | | |
* | | |
| | * |
* | | |
* | | |
| * | |
| | * |
| * | |
* | | |
| \ \ \ \
| * | | |
| / | | | |
| | / / /
| * | |
| | \ \ \
| | * | |
| | / | | |
| | | / /
| | * |
| | | \ \
| | | * |
| | | / | |
* | | | |
* | | | |
| \ \ \ \ \
| * | | | |
| / | | | | |
| | * | | |
| | * | | |
| | * | | |
| | / / / /
| * | | |
| | \ \ \ \
| | * | | |
| | / | | | |
* | | | | |
* | | | | |
* | | | | |
* | | | | |
* | | | | |
| | | | * |
* | | | | |
| \ \ \ \ \ \
| * | | | | |
| / | | | | | |
| | | | | * |
| | | | | / /
* | | | | |
| \ \ \ \ \ \
* | | | | | |
* | | | | | |
| | | | * | |
* | | | | | |
* | | | | | |
| \ \ \ \ \ \ \
| | | _ | _ | / / /
| | / | | | | |
| | | | * | |
| | | | * | |
| | | | * | |
| | | | * | |
| | | | * | |
| | | | * | |
| | | | / / /
| | | * | |
| | | * | |
| | | * | |
| | | / | | |
| | | * | |
| | | / | | |
| | | | / /
| | * | |
| | / | | |
| | | * |
| | | / /
| | * |
| * | |
| | \ \ \
| * | | |
| | * | |
| | / | | |
| | | / /
| | * |
| | | \ \
| | * | |
* | | | |
| \ | | | |
| * | | |
| * | | |
| * | | |
| | * | |
| * | | |
| | \ | | |
| * | | |
| | * | |
| | * | |
| * | | |
| * | | |
| * | | |
| * | | |
| * | | |
| * | | |
| * | | |
| * | | |
| | * | |
| * | | |
| * | | |
| * | | |
| * | | |
| | * | |
* | | | |
| \ | | | |
| | * | |
| * | | |
| | \ | | |
| | * | |
| | * | |
| | * | |
| | | * |
* | | | |
| \ | | | |
| | * | |
| | | / /
| * | |
| * | |
| | \ | |
* | | |
| \ | | |
| | * |
| | * |
| | * |
| * | |
| | * |
| * | |
| | * |
| | * |
| | * |
| * | |
| * | |
| * | |
| * | |
| * | |
| * | |
| * | |
* | | |
| \ | | |
| * | |
| | \ | |
| | * |
| | | \ \
* | | | |
| \ | | | |
| * | | |
| | \ | | |
| | * | |
| | | * |
| | | / /
* | | |
* | | |
| \ | | |
| * | |
| | \ | |
| | * |
| | * |
| | * |
| | | *
* | | |
| \ | | |
| * | |
| * | |
| | | *
| | | | \
* | | | |
| | _ | _ | /
| / | | |
| * | |
| | \ | |
| | * |
| | * |
| | * |
| | * |
| | * |
| * | |
* | | |
| \ | | |
| * | |
| / | | |
| | / /
| * |
| | \ \
| * | |
| * | |
* | | |
| \ | | |
| | * |
| * | |
| * | |
| * | |
* | | |
| \ | | |
| * | |
| * | |
| | * |
| | | \ \
| | | / /
| | / | |
| * | |
* | | |
| \ | | |
| * | |
* | | |
| \ | | |
| * | |
| | \ \ \
| * | | |
| * | | |
| | | * |
| * | | |
| * | | |
| | | / /
| | / | |
| | * |
* | | |
| \ | | |
| * | |
| * | |
| * | |
| * | |
| * | |
| | \ \ \
* | | | |
| \ | | | |
| * | | |
| * | | |
* | | | |
* | | | |
| \ | | | |
| | | | *
| | | | | \
| | _ | _ | _ | /
| / | | | |
| * | | |
* | | | |
* | | | |
| \ | | | |
| * | | |
| | \ \ \ \
| | | | / /
| | | / | |
| * | | |
| * | | |
| * | | |
| * | | |
| | * | |
| | | * |
| | | / /
| | / | |
* | | |
| \ | | |
| * | |
| * | |
| * | |
| * | |
| * | |
* | | |
| \ | | |
| * | |
| * | |
* | | |
| * | |
| * | |
| * | |
* | | |
* | | |
* | | |
| \ | | |
| * | |
* | | |
* | | |
* | | |
* | | |
| | | *
* | | |
| \ | | |
| * | |
| * | |
| * | |
`