Skip to content

Commit

Permalink
futher test coverage increase
Browse files Browse the repository at this point in the history
  • Loading branch information
emilwareus committed Sep 26, 2023
1 parent eace81c commit c4c1d3d
Show file tree
Hide file tree
Showing 3 changed files with 148 additions and 43 deletions.
34 changes: 23 additions & 11 deletions internal/resolution/pm/nuget/cmd_factory.go
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import (
"os/exec"
"path/filepath"
"regexp"
"sort"
"strings"
)

Expand All @@ -27,10 +28,6 @@ func (ExecPath) LookPath(file string) (string, error) {
return exec.LookPath(file)
}

type CmdFactory struct {
execPath IExecPath
}

var packagesConfigTemplate = `
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
Expand All @@ -44,17 +41,31 @@ var packagesConfigTemplate = `
</Project>
`

type CmdFactory struct {
execPath IExecPath
packageConfgRegex string
packagesConfigTemplate string
}

func NewCmdFactory(execPath IExecPath) CmdFactory {
return CmdFactory{
execPath: execPath,
packageConfgRegex: PackagesConfigRegex,
packagesConfigTemplate: packagesConfigTemplate,
}
}

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
// check regex with PackagesConfigRegex
packageConfig, err := regexp.Compile(PackagesConfigRegex)
packageConfig, err := regexp.Compile(cmdf.packageConfgRegex)
if err != nil {
return nil, err
}

if packageConfig.MatchString(file) {
file, err = convertPackagesConfigToCsproj(file)
file, err = cmdf.convertPackagesConfigToCsproj(file)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -92,14 +103,14 @@ type Package struct {
// that enables debricked to parse out transitive dependencies.
// This may add some additional framework dependencies that will not show up if
// we only scan the packages.config file.
func convertPackagesConfigToCsproj(filePath string) (string, error) {
func (cmdf CmdFactory) convertPackagesConfigToCsproj(filePath string) (string, error) {
packages, err := parsePackagesConfig(filePath)
if err != nil {
return "", err
}

targetFrameworksStr := collectUniqueTargetFrameworks(packages.Packages)
csprojContent, err := createCsprojContentWithTemplate(targetFrameworksStr, packages.Packages, packagesConfigTemplate)
csprojContent, err := cmdf.createCsprojContentWithTemplate(targetFrameworksStr, packages.Packages)
if err != nil {
return "", err
}
Expand Down Expand Up @@ -147,11 +158,12 @@ func collectUniqueTargetFrameworks(packages []Package) string {
}
}

sort.Strings(targetFrameworks) // Sort the targetFrameworks slice

return strings.Join(targetFrameworks, ";")
}

func createCsprojContentWithTemplate(targetFrameworksStr string, packages []Package, tmpl string) (string, error) {
tmplParsed, err := template.New("csproj").Parse(tmpl)
func (cmdf CmdFactory) createCsprojContentWithTemplate(targetFrameworksStr string, packages []Package) (string, error) {
tmplParsed, err := template.New("csproj").Parse(cmdf.packagesConfigTemplate)
if err != nil {
return "", err
}
Expand Down
153 changes: 124 additions & 29 deletions internal/resolution/pm/nuget/cmd_factory_test.go
Original file line number Diff line number Diff line change
@@ -1,17 +1,19 @@
package nuget

import (
"errors"
"os"
"path/filepath"
"testing"

"github.com/stretchr/testify/assert"
)

func TestMakeInstallCmd(t *testing.T) {
nugetCommand := "dotnet"

Check failure on line 13 in internal/resolution/pm/nuget/cmd_factory_test.go

View workflow job for this annotation

GitHub Actions / Lint

string `dotnet` has 5 occurrences, but such constant `nuget` already exists (goconst)
cmd, err := CmdFactory{
execPath: ExecPath{},
}.MakeInstallCmd(nugetCommand, "file")
cmd, err := NewCmdFactory(
ExecPath{},
).MakeInstallCmd(nugetCommand, "file")
assert.NoError(t, err)
assert.NotNil(t, cmd)
args := cmd.Args
Expand All @@ -21,9 +23,9 @@ func TestMakeInstallCmd(t *testing.T) {

func TestMakeInstallCmdPackagsConfig(t *testing.T) {
nugetCommand := "dotnet"
cmd, err := CmdFactory{
execPath: ExecPath{},
}.MakeInstallCmd(nugetCommand, "testdata/valid/packages.config")
cmd, err := NewCmdFactory(
ExecPath{},
).MakeInstallCmd(nugetCommand, "testdata/valid/packages.config")
assert.NoError(t, err)
assert.NotNil(t, cmd)
args := cmd.Args
Expand Down Expand Up @@ -127,28 +129,6 @@ func TestWriteContentToCsprojFile(t *testing.T) {
}
}

func TestConvertPackagesConfigToCsproj(t *testing.T) {
tests := []struct {
filePath string
wantError bool
}{
{"testdata/valid/packages.config", false},
{"testdata/invalid/packages.config", true},
}

for _, tt := range tests {
_, err := convertPackagesConfigToCsproj(tt.filePath)
if (err != nil) != tt.wantError {
t.Errorf("convertPackagesConfigToCsproj(%q) = %v, want error: %v", tt.filePath, err, tt.wantError)
}
}

// Cleanup: Remove the created .csproj file
if err := os.Remove("testdata/valid/packages.config.csproj"); err != nil {
t.Fatalf("Failed to remove test file: %v", err)
}
}

func TestWriteContentToCsprojFileErr(t *testing.T) {
tests := []struct {
name string
Expand Down Expand Up @@ -264,10 +244,125 @@ func TestCreateCsprojContent(t *testing.T) {

for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
_, err := createCsprojContentWithTemplate(test.targetFrameworksStr, test.packages, test.tmpl)
cmd := CmdFactory{
execPath: ExecPath{},
packageConfgRegex: PackagesConfigRegex,
packagesConfigTemplate: test.tmpl,
}
_, err := cmd.createCsprojContentWithTemplate(test.targetFrameworksStr, test.packages)
if (err != nil) != test.shouldFail {
t.Errorf("createCsprojContentWithTemplate() error = %v, shouldFail = %v", err, test.shouldFail)
}
})
}
}

func TestMakeInstallCmdBadPackagesConfigRegex(t *testing.T) {
nugetCommand := "dotnet"
cmd, err := CmdFactory{
execPath: ExecPath{},
packageConfgRegex: "[",
}.MakeInstallCmd(nugetCommand, "file")

assert.Error(t, err)
assert.Nil(t, cmd)
}

func TestMakeInstallCmdNotAccessToFile(t *testing.T) {
nugetCommand := "dotnet"
tempDir, err := os.MkdirTemp("", "TestMakeInstallCmdNotAccessToFile")
if err != nil {
panic(err)
}
defer os.RemoveAll(tempDir)

filePath := filepath.Join(tempDir, "packages.config")

file, err := os.Create(filePath)
if err != nil {
panic(err)
}
defer file.Close()

file.Chmod(0222) // write-only permissions

Check failure on line 287 in internal/resolution/pm/nuget/cmd_factory_test.go

View workflow job for this annotation

GitHub Actions / Lint

Error return value of `file.Chmod` is not checked (errcheck)

_, err = NewCmdFactory(
ExecPath{},
).MakeInstallCmd(nugetCommand, file.Name())

assert.Error(t, err)
}

type ExecPathErr struct {
}

func (ExecPathErr) LookPath(file string) (string, error) {
return "", errors.New("error")
}

func TestMakeInstallCmdExecPathError(t *testing.T) {
nugetCommand := "dotnet"
cmd, err := CmdFactory{
execPath: ExecPathErr{},
packageConfgRegex: PackagesConfigRegex,
}.MakeInstallCmd(nugetCommand, "file")

assert.Error(t, err)
assert.Nil(t, cmd)
}

func TestConvertPackagesConfigToCsproj(t *testing.T) {
tests := []struct {
name string
filePath string
wantError bool
packagesConfigTemplate string
setup func() string // function to set up the test environment
teardown func() // function to clean up after the test
}{
{"Valid packages config", "testdata/valid/packages.config", false, packagesConfigTemplate, nil, nil},
{"Invalid packages config", "testdata/invalid/packages.config", true, packagesConfigTemplate, nil, nil},
{"Bad template", "testdata/valid/packages.config", true, "{{.TargetFramewo", nil, nil},
{"File without write premisions", "testdata/valid/packages.config", true, packagesConfigTemplate,
func() string {
filename := "testdata/valid/packages.config.csproj"
file, err := os.Create(filename)
if err != nil {
t.Fatal(err)
}
defer file.Close()
file.Chmod(0222) // write-only permissions

Check failure on line 334 in internal/resolution/pm/nuget/cmd_factory_test.go

View workflow job for this annotation

GitHub Actions / Lint

Error return value of `file.Chmod` is not checked (errcheck)
return file.Name()

Check failure on line 335 in internal/resolution/pm/nuget/cmd_factory_test.go

View workflow job for this annotation

GitHub Actions / Lint

return with no blank line before (nlreturn)
},
nil,
},
}

for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if tt.setup != nil {
tt.setup() // set up the environment for the test
}

if tt.teardown != nil {
defer tt.teardown() // clean up after the test
}

cmd := CmdFactory{
execPath: ExecPath{},
packageConfgRegex: PackagesConfigRegex,
packagesConfigTemplate: tt.packagesConfigTemplate,
}
_, err := cmd.convertPackagesConfigToCsproj(tt.filePath)
if (err != nil) != tt.wantError {
t.Errorf("convertPackagesConfigToCsproj(%q) = %v, want error: %v", tt.filePath, err, tt.wantError)
}

})
}

// Cleanup: Remove the created .csproj file
if err := os.Remove("testdata/valid/packages.config.csproj"); err != nil {
t.Fatalf("Failed to remove test file: %v", err)
}
}
4 changes: 1 addition & 3 deletions internal/resolution/pm/nuget/strategy.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,7 @@ func (s Strategy) Invoke() ([]job.IJob, error) {
jobs = append(jobs, NewJob(
file,
true,
CmdFactory{
execPath: ExecPath{},
},
NewCmdFactory(ExecPath{}),
),
)
}
Expand Down

0 comments on commit c4c1d3d

Please sign in to comment.