@@ -71,18 +71,18 @@ func TestBuildScanOptions(t *testing.T) {
7171 expectedOptions : "--full-history --all def456..HEAD" ,
7272 },
7373 {
74- name : "Base commit takes precedence over depth " ,
74+ name : "Base commit with depth: both flags are used " ,
7575 scanAllBranches : false ,
7676 depth : 10 ,
7777 baseCommit : "ghi789" ,
78- expectedOptions : "--full-history ghi789..HEAD" ,
78+ expectedOptions : "--full-history ghi789..HEAD -n 10 " ,
7979 },
8080 {
81- name : "Base commit with all branches takes precedence over depth " ,
81+ name : "Base commit with all branches and depth: all flags are used " ,
8282 scanAllBranches : true ,
8383 depth : 15 ,
8484 baseCommit : "jkl012" ,
85- expectedOptions : "--full-history --all jkl012..HEAD" ,
85+ expectedOptions : "--full-history --all jkl012..HEAD -n 15 " ,
8686 },
8787 }
8888
@@ -491,6 +491,7 @@ func TestExtractChanges(t *testing.T) {
491491 name string
492492 fragments []* gitdiff.TextFragment
493493 expectedChunks int
494+ expectedError error
494495 description string
495496 }{
496497 {
@@ -523,69 +524,151 @@ func TestExtractChanges(t *testing.T) {
523524 expectedChunks : 3 ,
524525 description : "Should handle mixed add/delete operations in single chunk" ,
525526 },
527+ {
528+ name : "File diff size exceeded" ,
529+ fragments : createLargeTestFragments (51 * 1024 * 1024 ), // 51MB
530+ expectedChunks : 0 ,
531+ description : "Should return error when file diff size exceeds limit" ,
532+ expectedError : ErrFileDiffSizeExceeded ,
533+ },
526534 }
527535
528536 for _ , tt := range tests {
529537 t .Run (tt .name , func (t * testing.T ) {
530538 changesPool := newGitChangesPool (0 )
531- chunks := extractChanges (changesPool , tt .fragments )
539+ chunks , err := extractChanges (changesPool , tt .fragments )
532540
541+ assert .ErrorIs (t , err , tt .expectedError )
533542 assert .Equal (t , tt .expectedChunks , len (chunks ), tt .description )
534543
535- // Verify memory is freed for non-nil fragments
536- for _ , fragment := range tt .fragments {
537- if fragment != nil {
538- for _ , line := range fragment .Lines {
539- assert .Empty (t , line .Line , "Line content should be cleared to free memory" )
544+ if tt .expectedError == nil {
545+ // Verify memory is freed for non-nil fragments
546+ for _ , fragment := range tt .fragments {
547+ if fragment != nil {
548+ for _ , line := range fragment .Lines {
549+ assert .Empty (t , line .Line , "Line content should be cleared to free memory" )
550+ }
540551 }
541552 }
542- }
543553
544- // Verify chunks contain expected content types
545- for _ , chunk := range chunks {
546- if tt .expectedChunks > 0 {
547- // At least one chunk should have some content
548- hasContent := chunk .Added != "" || chunk .Removed != ""
549- assert .True (t , hasContent , "Chunk should contain added or removed content" )
554+ // Verify chunks contain expected content types
555+ for _ , chunk := range chunks {
556+ if tt .expectedChunks > 0 {
557+ // At least one chunk should have some content
558+ hasContent := chunk .Added != "" || chunk .Removed != ""
559+ assert .True (t , hasContent , "Chunk should contain added or removed content" )
560+ }
550561 }
551562 }
552563 })
553564 }
554565}
555566
556567func TestProcessFileDiff (t * testing.T ) {
557- plugin := & GitPlugin {
558- Plugin : Plugin {},
559- projectName : "test-project" ,
560- gitChangesPool : newGitChangesPool (0 ),
568+ tests := []struct {
569+ name string
570+ fragmentSize int
571+ isBinary bool
572+ isDelete bool
573+ expectedItems int
574+ }{
575+ {
576+ name : "normal file with small diff" ,
577+ fragmentSize : 2000 , // 2KB
578+ expectedItems : 2 ,
579+ },
580+ {
581+ name : "normal file with large diff under limit" ,
582+ fragmentSize : 2 * 1024 * 1024 , // 2MiB
583+ expectedItems : 16 , // (2000 KiB /256 KiB = 8 chunks) x 2 (added and removed)
584+ },
585+ {
586+ name : "file exceeding size limit" ,
587+ fragmentSize : 60 * 1024 * 1024 , // 60MiB - exceeds 50MiB limit
588+ expectedItems : 0 ,
589+ },
590+ {
591+ name : "binary file" ,
592+ fragmentSize : 1024 ,
593+ isBinary : true ,
594+ expectedItems : 0 ,
595+ },
596+ {
597+ name : "deleted file" ,
598+ fragmentSize : 1024 ,
599+ isDelete : true ,
600+ expectedItems : 1 ,
601+ },
602+ {
603+ name : "empty fragments" ,
604+ fragmentSize : 0 ,
605+ expectedItems : 0 ,
606+ },
561607 }
562608
563- // Create test file with large diff
609+ for _ , tt := range tests {
610+ t .Run (tt .name , func (t * testing.T ) {
611+ plugin := & GitPlugin {
612+ Plugin : Plugin {},
613+ projectName : "test-project" ,
614+ gitChangesPool : newGitChangesPool (0 ),
615+ }
616+
617+ // Create test file
618+ file := createTestFile ("test-file" , "abc123" , tt .name , tt .fragmentSize , tt .isBinary , tt .isDelete )
619+
620+ items := make (chan ISourceItem , 100 )
621+
622+ plugin .processFileDiff (file , items )
623+ close (items )
624+
625+ // Collect all items
626+ var itemCount int
627+ var collectedItems []ISourceItem
628+ for item := range items {
629+ itemCount ++
630+ collectedItems = append (collectedItems , item )
631+ assert .NotNil (t , item .GetContent (), "Item content should not be nil" )
632+ assert .NotEmpty (t , item .GetID (), "Item ID should not be empty" )
633+ }
634+
635+ assert .Equal (t , tt .expectedItems , itemCount )
636+ if itemCount > 0 {
637+ for _ , item := range collectedItems {
638+ assert .Contains (t , item .GetID (), "abc123" , "Item ID should contain commit SHA" )
639+ assert .Contains (t , item .GetID (), "test-file" , "Item ID should contain file name" )
640+
641+ // Validate GitInfo
642+ if gitInfo := item .GetGitInfo (); gitInfo != nil {
643+ assert .NotNil (t , gitInfo .Hunks , "GitInfo should have hunks" )
644+ assert .True (t , gitInfo .ContentType == AddedContent || gitInfo .ContentType == RemovedContent ,
645+ "GitInfo should have valid content type" )
646+ }
647+ }
648+ }
649+ })
650+ }
651+ }
652+
653+ // createTestFile creates a gitdiff.File for testing with specified parameters
654+ func createTestFile (fileName , commitSHA , commitTitle string , fragmentSize int , isBinary , isDelete bool ) * gitdiff.File {
564655 file := & gitdiff.File {
565- NewName : "test-file.go" ,
566- OldName : "test-file.go" ,
656+ NewName : fileName ,
657+ OldName : fileName ,
567658 PatchHeader : & gitdiff.PatchHeader {
568- SHA : "abc123" ,
569- Title : "Test commit" ,
659+ SHA : commitSHA ,
660+ Title : commitTitle ,
570661 },
571- TextFragments : createLargeTestFragments (2 * 1024 * 1024 ), // 2MB
662+ IsBinary : isBinary ,
663+ IsDelete : isDelete ,
572664 }
573665
574- items := make (chan ISourceItem , 100 )
575-
576- plugin .processFileDiff (file , items )
577- close (items )
578-
579- // Collect all items
580- var itemCount int
581- for item := range items {
582- itemCount ++
583- assert .NotNil (t , item .GetContent (), "Item content should not be nil" )
584- assert .NotEmpty (t , item .GetID (), "Item ID should not be empty" )
666+ // Only create fragments for non-binary files with content
667+ if ! isBinary && fragmentSize > 0 {
668+ file .TextFragments = createLargeTestFragments (fragmentSize )
585669 }
586670
587- // Should have created multiple chunks and therefore multiple items
588- assert .Greater (t , itemCount , 1 , "Should create multiple items for large file" )
671+ return file
589672}
590673
591674func TestStringBuilderPool (t * testing.T ) {
@@ -637,11 +720,11 @@ func TestStringBuilderPool(t *testing.T) {
637720}
638721
639722func createLargeTestFragments (totalSize int ) []* gitdiff.TextFragment {
640- lineSize := 1024 // 1KB per line
641- numLines := totalSize / lineSize
723+ lineSize := 1024 // 1KiB per line
724+ numLines := ( totalSize + lineSize - 1 ) / lineSize // Ceiling division
642725 lines := make ([]gitdiff.Line , numLines )
643726
644- for i := 0 ; i < numLines ; i ++ {
727+ for i := range numLines {
645728 op := gitdiff .OpAdd
646729 if i % 2 == 0 {
647730 op = gitdiff .OpDelete
0 commit comments