diff --git a/internal/resolution/pm/nuget/cmd_factory.go b/internal/resolution/pm/nuget/cmd_factory.go
index 75ca887a..1f71f550 100644
--- a/internal/resolution/pm/nuget/cmd_factory.go
+++ b/internal/resolution/pm/nuget/cmd_factory.go
@@ -31,6 +31,19 @@ type CmdFactory struct {
execPath IExecPath
}
+var packagesConfigTemplate = `
+
+
+ {{.TargetFrameworks}}
+
+
+ {{- range .Packages}}
+
+ {{- end}}
+
+
+`
+
func (cmdf CmdFactory) MakeInstallCmd(command string, file string) (*exec.Cmd, error) {
// If the file is a packages.config file, convert it to a .csproj file
@@ -86,7 +99,7 @@ func convertPackagesConfigToCsproj(filePath string) (string, error) {
}
targetFrameworksStr := collectUniqueTargetFrameworks(packages.Packages)
- csprojContent, err := createCsprojContent(targetFrameworksStr, packages.Packages)
+ csprojContent, err := createCsprojContentWithTemplate(targetFrameworksStr, packages.Packages, packagesConfigTemplate)
if err != nil {
return "", err
}
@@ -137,19 +150,7 @@ func collectUniqueTargetFrameworks(packages []Package) string {
return strings.Join(targetFrameworks, ";")
}
-func createCsprojContent(targetFrameworksStr string, packages []Package) (string, error) {
- tmpl := `
-
-
- {{.TargetFrameworks}}
-
-
- {{- range .Packages}}
-
- {{- end}}
-
-
-`
+func createCsprojContentWithTemplate(targetFrameworksStr string, packages []Package, tmpl string) (string, error) {
tmplParsed, err := template.New("csproj").Parse(tmpl)
if err != nil {
return "", err
@@ -168,6 +169,7 @@ func createCsprojContent(targetFrameworksStr string, packages []Package) (string
}
func writeContentToCsprojFile(newFilename string, content string) error {
+
csprojFile, err := os.Create(newFilename)
if err != nil {
return err
@@ -175,9 +177,6 @@ func writeContentToCsprojFile(newFilename string, content string) error {
defer csprojFile.Close()
_, err = csprojFile.WriteString(content)
- if err != nil {
- return err
- }
- return nil
+ return err
}
diff --git a/internal/resolution/pm/nuget/cmd_factory_test.go b/internal/resolution/pm/nuget/cmd_factory_test.go
index f971919b..44de7025 100644
--- a/internal/resolution/pm/nuget/cmd_factory_test.go
+++ b/internal/resolution/pm/nuget/cmd_factory_test.go
@@ -35,21 +35,64 @@ func TestMakeInstallCmdPackagsConfig(t *testing.T) {
t.Fatalf("Failed to remove test file: %v", err)
}
}
-
func TestParsePackagesConfig(t *testing.T) {
tests := []struct {
- filePath string
- wantError bool
+ name string
+ setup func() string // function to set up the test environment
+ teardown func() // function to clean up after the test
+ shouldFail bool
}{
- {"testdata/valid/packages.config", false},
- {"testdata/invalid/packages.config", true},
+ {
+ name: "Non-existent file",
+ setup: func() string {
+ return "nonexistent_file.config"
+ },
+ shouldFail: true,
+ },
+ {
+ name: "Unreadable file",
+ setup: func() string {
+ file, err := os.CreateTemp("", "unreadable_*.config")
+ if err != nil {
+ t.Fatal(err)
+ }
+ file.Chmod(0222) // write-only permissions
+ return file.Name()
+ },
+ teardown: func() {
+ os.Remove("unreadable_file.config") // clean up the unreadable file
+ },
+ shouldFail: true,
+ },
+ {
+ name: "Malformed XML",
+ setup: func() string {
+ file, err := os.CreateTemp("", "malformed_*.config")
+ if err != nil {
+ t.Fatal(err)
+ }
+ file.WriteString("malformed xml content")
+ return file.Name()
+ },
+ teardown: func() {
+ os.Remove("malformed_file.config") // clean up the malformed file
+ },
+ shouldFail: true,
+ },
}
- for _, tt := range tests {
- _, err := parsePackagesConfig(tt.filePath)
- if (err != nil) != tt.wantError {
- t.Errorf("parsePackagesConfig(%q) = %v, want error: %v", tt.filePath, err, tt.wantError)
- }
+ for _, test := range tests {
+ t.Run(test.name, func(t *testing.T) {
+ filePath := test.setup()
+ if test.teardown != nil {
+ defer test.teardown() // clean up after the test
+ }
+
+ _, err := parsePackagesConfig(filePath)
+ if (err != nil) != test.shouldFail {
+ t.Errorf("parsePackagesConfig() error = %v, shouldFail = %v", err, test.shouldFail)
+ }
+ })
}
}
@@ -66,25 +109,6 @@ func TestCollectUniqueTargetFrameworks(t *testing.T) {
}
}
-func TestCreateCsprojContent(t *testing.T) {
- packages := []Package{
- {ID: "Test.Package.1", Version: "1.0.0", TargetFramework: "net45"},
- {ID: "Test.Package.2", Version: "2.0.0", TargetFramework: "net46"},
- }
- targetFrameworksStr := "net45;net46"
-
- got, err := createCsprojContent(targetFrameworksStr, packages)
- if err != nil {
- t.Fatalf("createCsprojContent() failed: %v", err)
- }
-
- // We're just checking if the function returns a non-empty string
- // For a more rigorous test, we'd check the exact content of the string
- if got == "" {
- t.Errorf("createCsprojContent() returned an empty string")
- }
-}
-
func TestWriteContentToCsprojFile(t *testing.T) {
newFilename := "testdata/test_output.csproj"
content := ""
@@ -124,3 +148,126 @@ func TestConvertPackagesConfigToCsproj(t *testing.T) {
t.Fatalf("Failed to remove test file: %v", err)
}
}
+
+func TestWriteContentToCsprojFileErr(t *testing.T) {
+ tests := []struct {
+ name string
+ filename string
+ content string
+ shouldFail bool
+ setup func() // function to set up the environment for the test
+ teardown func() // function to clean up after the test
+ }{
+ {
+ name: "Valid file name and content",
+ filename: "test.csproj",
+ content: "",
+ shouldFail: false,
+ teardown: func() {
+ os.Remove("test.csproj") // Clean up the created file
+ },
+ },
+ {
+ name: "Invalid file name",
+ filename: "", // Empty filename is invalid
+ content: "",
+ shouldFail: true,
+ },
+ {
+ name: "Write to a read-only file",
+ filename: "readonly.csproj",
+ content: "",
+ shouldFail: true,
+ setup: func() {
+ // Create a read-only file
+ file, err := os.Create("readonly.csproj")
+ if err != nil {
+ panic(err)
+ }
+ file.Close()
+ os.Chmod("readonly.csproj", 0444) // Set file permissions to read-only
+ },
+ teardown: func() {
+ os.Remove("readonly.csproj") // Clean up the read-only file
+ },
+ },
+ }
+
+ for _, test := range tests {
+ t.Run(test.name, func(t *testing.T) {
+ if test.setup != nil {
+ test.setup() // set up the environment for the test
+ }
+ err := writeContentToCsprojFile(test.filename, test.content)
+ if (err != nil) != test.shouldFail {
+ t.Errorf("writeContentToCsprojFile() error = %v, shouldFail = %v", err, test.shouldFail)
+ }
+ if test.teardown != nil {
+ test.teardown() // clean up after the test
+ }
+ })
+ }
+}
+
+func TestCreateCsprojContent(t *testing.T) {
+ tests := []struct {
+ name string
+ targetFrameworksStr string
+ packages []Package
+ shouldFail bool
+ tmpl string
+ }{
+ {
+ name: "Valid template action",
+ targetFrameworksStr: "netcoreapp3.1",
+ packages: []Package{{ID: "SomePackage", Version: "1.0.0"}},
+ shouldFail: false,
+ tmpl: packagesConfigTemplate,
+ },
+ {
+ name: "Invalid template action",
+ targetFrameworksStr: "netcoreapp3.1",
+ packages: []Package{{ID: "SomePackage", Version: "1.0.0"}},
+ shouldFail: true,
+ tmpl: `
+
+
+ {{.TargetFrameworks}}
+
+
+ {{- range .Packages}}
+
+ {{- end}}
+
+
+ `,
+ },
+ {
+ name: "Non-existent field",
+ targetFrameworksStr: "netcoreapp3.1",
+ packages: []Package{{ID: "SomePackage", Version: "1.0.0"}},
+ shouldFail: true,
+ tmpl: `
+
+
+ {{.NonExistentField}}
+
+
+ {{- range .Packages}}
+
+ {{- end}}
+
+
+ `,
+ },
+ }
+
+ for _, test := range tests {
+ t.Run(test.name, func(t *testing.T) {
+ _, err := createCsprojContentWithTemplate(test.targetFrameworksStr, test.packages, test.tmpl)
+ if (err != nil) != test.shouldFail {
+ t.Errorf("createCsprojContentWithTemplate() error = %v, shouldFail = %v", err, test.shouldFail)
+ }
+ })
+ }
+}