diff --git a/internal/fingerprint/fingerprint.go b/internal/fingerprint/fingerprint.go index 8a6346bd..1ea72a6b 100644 --- a/internal/fingerprint/fingerprint.go +++ b/internal/fingerprint/fingerprint.go @@ -258,8 +258,10 @@ func (f *Fingerprints) Len() int { return len(f.Entries) } +var osCreate = os.Create + func (f *Fingerprints) ToFile(ouputFile string) error { - file, err := os.Create(ouputFile) + file, err := osCreate(ouputFile) if err != nil { return err } @@ -278,10 +280,6 @@ func (f *Fingerprints) ToFile(ouputFile string) error { } -func (f *Fingerprints) Append(fingerprint FileFingerprint) { - f.Entries = append(f.Entries, fingerprint) -} - var filesToUnzip = []string{".jar", ".nupkg"} func shouldUnzip(filename string) bool { diff --git a/internal/fingerprint/fingerprint_test.go b/internal/fingerprint/fingerprint_test.go index e8349d4c..4099d658 100644 --- a/internal/fingerprint/fingerprint_test.go +++ b/internal/fingerprint/fingerprint_test.go @@ -1,6 +1,7 @@ package fingerprint import ( + "errors" "fmt" "os" "path/filepath" @@ -64,46 +65,80 @@ func TestShouldProcessFile(t *testing.T) { t.Fatalf("Failed to create symbolic link %s: %v", testLink, err) } - // Test with a regular file - fileInfo, err := os.Stat(testFile) - if err != nil { - t.Fatalf("Failed to get file info for %s: %v", testFile, err) - } - if !shouldProcessFile(fileInfo, []string{}, testFile) { - t.Errorf("Expected shouldProcessFile to return true for %s, but it returned false", testFile) - } - - // Test with a symbolic link - linkInfo, err := os.Stat(testLink) - if err != nil { - t.Fatalf("Failed to get file info for %s: %v", testLink, err) - } - - if shouldProcessFile(linkInfo, []string{}, testLink) { - t.Errorf("Expected shouldProcessFile to return false for %s, but it returned true", testLink) - } - - // Test Excluded - if shouldProcessFile(fileInfo, []string{"**/test.py"}, testFile) { - t.Errorf("Expected shouldProcessFile to return true for %s, but it returned false", testFile) - } - - isSymlinkFunc = mockSymlink - - if shouldProcessFile(fileInfo, []string{}, testFile) { - t.Errorf("Expected shouldProcessFile to return false for %s, but it returned true", testFile) - } - - errorString = "The system cannot find the path specified." - if !shouldProcessFile(fileInfo, []string{}, testFile) { - t.Errorf("Expected shouldProcessFile to return true for %s, but it returned false", testFile) + tests := []struct { + name string + filePath string + excludes []string + mock func() + want bool + }{ + { + name: "Test with a regular file", + filePath: testFile, + excludes: []string{}, + mock: func() {}, + want: true, + }, + { + name: "Test with a symbolic link", + filePath: testLink, + excludes: []string{}, + mock: func() {}, + want: false, + }, + { + name: "Test Excluded", + filePath: testFile, + excludes: []string{"**/test.py"}, + mock: func() {}, + want: false, + }, + { + name: "Test with mockSymlink", + filePath: testFile, + excludes: []string{}, + mock: func() { isSymlinkFunc = mockSymlink }, + want: false, + }, + { + name: "Test with errorString: The system cannot find the path specified.", + filePath: testFile, + excludes: []string{}, + mock: func() { errorString = "The system cannot find the path specified." }, + want: true, + }, + { + name: "Test with errorString: not a directory", + filePath: testFile, + excludes: []string{}, + mock: func() { errorString = "not a directory" }, + want: true, + }, + { + name: "Test with generic error", + filePath: testFile, + excludes: []string{}, + mock: func() { errorString = "generic error" }, + want: false, + }, } - errorString = "not a directory" - if !shouldProcessFile(fileInfo, []string{}, testFile) { - t.Errorf("Expected shouldProcessFile to return false for %s, but it returned true", testFile) + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + defer func() { errorString = "mock error" }() + tt.mock() + fileInfo, err := os.Stat(tt.filePath) + if err != nil { + t.Fatalf("Failed to get file info for %s: %v", tt.filePath, err) + } + if got := shouldProcessFile(fileInfo, tt.excludes, tt.filePath); got != tt.want { + t.Errorf("Expected shouldProcessFile to return %v for %s, but it returned %v", tt.want, tt.filePath, got) + } + }) } + // Reset isSymlinkFunc and errorString + isSymlinkFunc = isSymlink } func TestNewFingerprinter(t *testing.T) { @@ -174,16 +209,68 @@ func TestComputeMD5(t *testing.T) { } func TestFingerprintsToFile(t *testing.T) { - fingerprints := Fingerprints{} - fingerprints.Entries = append(fingerprints.Entries, FileFingerprint{path: "path", contentLength: 10, fingerprint: []byte("fingerprint")}) - // Create temp dir - dir, err := os.MkdirTemp("", "test") - assert.NoError(t, err) - defer os.RemoveAll(dir) - // Write fingerprints to file - err = fingerprints.ToFile(dir + "/fingerprints.wfp") - assert.NoError(t, err) + tests := []struct { + name string + outputFile string + setupMock func() + expectedError bool + }{ + { + name: "Successful write", + outputFile: "fingerprints.wfp", + setupMock: func() {}, + expectedError: false, + }, + { + name: "Failed to create file", + setupMock: func() { + osCreate = func(name string) (*os.File, error) { + return nil, errors.New("forced error") + } + }, + outputFile: "test/fingerprints.wfp", + expectedError: true, + }, + { + name: "Failed to write to file", + setupMock: func() { + osCreate = func(name string) (*os.File, error) { + return os.Create("test/fingerprints.wfp") + } + }, + outputFile: "/invalid/path/fingerprints.wfp", + expectedError: true, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + // Reset osCreate to its original function after each test + defer func() { osCreate = os.Create }() + + // Setup the mock function + tt.setupMock() + // Create temp dir + dir, err := os.MkdirTemp("", "test") + if err != nil { + t.Fatalf("Failed to create temporary directory: %v", err) + } + defer os.RemoveAll(dir) + + // Create fingerprints + fingerprints := Fingerprints{} + fingerprints.Entries = append(fingerprints.Entries, FileFingerprint{path: "path", contentLength: 10, fingerprint: []byte("fingerprint")}) + + // Write fingerprints to file + err = fingerprints.ToFile(filepath.Join(dir, tt.outputFile)) + if tt.expectedError { + assert.Error(t, err) + } else { + assert.NoError(t, err) + } + }) + } } func TestShouldUnzip(t *testing.T) { @@ -262,3 +349,27 @@ func TestInMemFingerprintingCompressedContent(t *testing.T) { }) } } + +func TestComputeMD5ForFile(t *testing.T) { + tests := []struct { + name string + file string + wantErr bool + }{ + { + name: "Non-existent file", + file: "non_existent_file.txt", + wantErr: true, + }, + // Add more test cases as needed + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + _, err := computeMD5ForFile(tt.file) + if (err != nil) != tt.wantErr { + t.Errorf("computeMD5ForFile() error = %v, wantErr %v", err, tt.wantErr) + } + }) + } +}