Skip to content

Commit

Permalink
add unit tests to code areas (#45)
Browse files Browse the repository at this point in the history
  • Loading branch information
davidjpeacock committed Mar 27, 2024
2 parents 329cb6f + cfdee97 commit a47d82e
Show file tree
Hide file tree
Showing 36 changed files with 8,899 additions and 81 deletions.
4 changes: 4 additions & 0 deletions Makefile
Expand Up @@ -16,3 +16,7 @@ clean:
# run linter
lint:
golangci-lint run --enable-all

# run unit tests
test:
go test -v ./...
4 changes: 3 additions & 1 deletion go.mod
Expand Up @@ -9,12 +9,14 @@ require (
)

require (
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc // indirect
github.com/fsnotify/fsnotify v1.6.0 // indirect
github.com/hashicorp/hcl v1.0.0 // indirect
github.com/inconshreveable/mousetrap v1.1.0 // indirect
github.com/magiconair/properties v1.8.7 // indirect
github.com/mitchellh/mapstructure v1.5.0 // indirect
github.com/pelletier/go-toml/v2 v2.1.0 // indirect
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 // indirect
github.com/sagikazarmark/locafero v0.3.0 // indirect
github.com/sagikazarmark/slog-shim v0.1.0 // indirect
github.com/sirupsen/logrus v1.9.0 // indirect
Expand All @@ -23,7 +25,7 @@ require (
github.com/spf13/cast v1.5.1 // indirect
github.com/spf13/pflag v1.0.5 // indirect
github.com/spf13/viper v1.17.0 // indirect
github.com/stretchr/testify v1.8.4 // indirect
github.com/stretchr/testify v1.9.0 // indirect
github.com/subosito/gotenv v1.6.0 // indirect
go.uber.org/atomic v1.9.0 // indirect
go.uber.org/multierr v1.9.0 // indirect
Expand Down
4 changes: 4 additions & 0 deletions go.sum
Expand Up @@ -51,6 +51,7 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc h1:U9qPSI2PIWSS1VwoXQT9A3Wy9MM3WgvqSxFWenqJduM=
github.com/davecgh/go-spew v1.1.2-0.20180830191138-d8f796af33cc/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4=
github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98=
Expand Down Expand Up @@ -146,6 +147,7 @@ github.com/pkg/sftp v1.13.1/go.mod h1:3HaPG6Dq1ILlpPZRO0HVMrsydcdLt6HRDccSgb87qR
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2 h1:Jamvg5psRIccs7FGNTlIRMkT8wgtp5eCXdBlqhYGL6U=
github.com/pmezard/go-difflib v1.0.1-0.20181226105442-5d4384ee4fb2/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
github.com/russross/blackfriday/v2 v2.1.0/go.mod h1:+Rmxgy9KzJVeS9/2gXHxylqXiyQDYRxCVz55jmeOWTM=
Expand Down Expand Up @@ -180,6 +182,8 @@ github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ
github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4=
github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk=
github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo=
github.com/stretchr/testify v1.9.0 h1:HtqpIVDClZ4nwg75+f6Lvsy/wHu+3BoSGCbBAcpTsTg=
github.com/stretchr/testify v1.9.0/go.mod h1:r2ic/lqez/lEtzL7wO/rwa5dbSLXVDPFyf8C91i36aY=
github.com/subosito/gotenv v1.6.0 h1:9NlTDc1FTs4qu0DDq7AEtTPNw6SVm7uBMsUCUjABIf8=
github.com/subosito/gotenv v1.6.0/go.mod h1:Dk4QP5c2W3ibzajGcXpNraDfq2IrhjMIvMSWPKKo0FU=
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
Expand Down
23 changes: 23 additions & 0 deletions pkg/common/utils.go
Expand Up @@ -96,6 +96,20 @@ func TestSshConnection(sshCmd string) bool {
return true
}

func TestEqualSlice(a []string, b []string) bool {
if len(a) != len(b) {
fmt.Println(len(a), len(b))
return false
}
for i := range a {
if a[i] != b[i] {
fmt.Println(a[i], b[i])
return false
}
}
return true
}

func StringInSlice(a string, list []string) bool {
for _, b := range list {
if b == a {
Expand All @@ -105,6 +119,15 @@ func StringInSlice(a string, list []string) bool {
return false
}

func SliceIndex(element string, data []string) int {
for k, v := range data {
if element == v {
return k
}
}
return -1
}

func GetNestedFieldValue(data interface{}, keyName string) interface{} {
val := reflect.ValueOf(data)
for val.Kind() == reflect.Ptr || val.Kind() == reflect.Interface {
Expand Down
209 changes: 209 additions & 0 deletions pkg/common/utils_test.go
@@ -0,0 +1,209 @@
/*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
* Copyright 2023 Red Hat, Inc.
*
*/
package common_test

import (
"testing"

"github.com/openstack-k8s-operators/os-diff/pkg/common"
)

// Test case for function stringInSlice
func TestStringInSlice(t *testing.T) {
testCases := []struct {
name string
inputStr string
inputList []string
expected bool
}{
{"String in slice - positive case", "apple", []string{"apple", "banana", "cherry"}, true},
{"String not in slice - negative case", "pear", []string{"apple", "banana", "cherry"}, false},
{"Empty slice - edge case", "apple", []string{}, false},
{"Empty string - edge case", "", []string{"apple", "banana", "cherry"}, false},
{"String at the beginning of the slice", "apple", []string{"apple", "banana", "cherry"}, true},
{"String at the end of the slice", "cherry", []string{"apple", "banana", "cherry"}, true},
{"String in slice with duplicates", "apple", []string{"apple", "apple", "apple"}, true},
}

for _, tc := range testCases {
t.Run(tc.name, func(t *testing.T) {
result := common.StringInSlice(tc.inputStr, tc.inputList)
if result != tc.expected {
t.Errorf("Expected %v but got %v for input string %s in slice %v", tc.expected, result, tc.inputStr, tc.inputList)
}
})
}
}

// Test case for function sliceIndex
func TestSliceIndex(t *testing.T) {
tests := []struct {
name string
element string
data []string
expected int
}{
{
name: "Element exists in data",
element: "apple",
data: []string{"orange", "banana", "apple", "grape"},
expected: 2,
},
{
name: "Element does not exist in data",
element: "pear",
data: []string{"orange", "banana", "apple", "grape"},
expected: -1,
},
{
name: "Element is empty",
element: "",
data: []string{"orange", "banana", "apple", "grape"},
expected: -1,
},
{
name: "Data is empty",
element: "apple",
data: []string{},
expected: -1,
},
{
name: "Duplicate elements in data",
element: "apple",
data: []string{"orange", "banana", "apple", "apple", "grape"},
expected: 2,
},
}

for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
result := common.SliceIndex(test.element, test.data)
if result != test.expected {
t.Errorf("Expected index %v, but got %v", test.expected, result)
}
})
}
}

// Test case for function isIni
func TestIsIni(t *testing.T) {
tests := []struct {
name string
data []byte
expected bool
}{
{
name: "Single character ini",
data: []byte{'['},
expected: true,
},
{
name: "First character is not a bracket",
data: []byte{'a', 'b', 'c'},
expected: false,
},
{
name: "First character is a bracket in a larger data set",
data: []byte{'[', 'a', 'b', 'c'},
expected: true,
},
}

for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
result := common.IsIni(test.data)
if result != test.expected {
t.Errorf("For data %v, expected %t, but got %t", test.data, test.expected, result)
}
})
}
}

// Test case for function isYaml
func TestIsYaml(t *testing.T) {
// Test when valid YAML data is provided
yamlData := []byte("key: value\n")
if !common.IsYaml(yamlData) {
t.Errorf("Expected isYaml to return true for valid YAML data, but it returned false")
}

// Test when invalid YAML data is provided
invalidYamlData := []byte("key: value:")
if common.IsYaml(invalidYamlData) {
t.Errorf("Expected isYaml to return false for invalid YAML data, but it returned true")
}

// Test when empty data is provided
emptyData := []byte("{")
if common.IsYaml(emptyData) {
t.Errorf("Expected isYaml to return false for empty data, but it returned true")
}
}

// Test case for function isJson
func TestIsJson_ValidJson(t *testing.T) {
data := []byte(`{"name": "John", "age": 30}`)
result := common.IsJson(data)
if !result {
t.Errorf("Expected isJson to return true for valid JSON, but got false")
}
}

func TestIsJson_InvalidJson(t *testing.T) {
data := []byte(`{invalid_json}`)
result := common.IsJson(data)
if result {
t.Errorf("Expected isJson to return false for invalid JSON, but got true")
}
}

func TestIsJson_EmptyJson(t *testing.T) {
data := []byte(`{}`)
result := common.IsJson(data)
if !result {
t.Errorf("Expected isJson to return true for empty JSON, but got false")
}
}

func TestIsJson_EmptyData(t *testing.T) {
data := []byte(``)
result := common.IsJson(data)
if result {
t.Errorf("Expected isJson to return false for empty data, but got true")
}
}

// Test case for function isJson
func TestIsJson(t *testing.T) {
// Test valid JSON data
jsonData := []byte(`{"key": "value"}`)
if !common.IsJson(jsonData) {
t.Error("Expected true for valid JSON data")
}

// Test invalid JSON data
invalidJsonData := []byte(`{"key": "value"`)
if common.IsJson(invalidJsonData) {
t.Error("Expected false for invalid JSON data")
}

// Test empty data
emptyData := []byte("")
if common.IsJson(emptyData) {
t.Error("Expected false for empty data")
}
}
12 changes: 7 additions & 5 deletions pkg/godiff/compare.go
Expand Up @@ -24,13 +24,15 @@ import (
"os"
"path/filepath"
"strings"

"github.com/openstack-k8s-operators/os-diff/pkg/common"
)

var Reset = "\033[0m"
var Red = "\033[31m"
var Green = "\033[32m"

func writeReport(content []string, reportPath string) error {
func WriteReport(content []string, reportPath string) error {

path, _ := filepath.Split(reportPath)
if _, err := os.Stat(path); os.IsNotExist(err) {
Expand Down Expand Up @@ -98,7 +100,7 @@ func CompareFiles(origin string, dest string, print bool, verbose bool) ([]strin
return nil, errors.New("Failed to open file: '" + dest + "'. " + err.Error())
}
// Detect type
if isIni(orgContent) && isIni(destContent) {
if common.IsIni(orgContent) && common.IsIni(destContent) {
log.Info("Files detected as Ini files, start to process contents")
report, err = CompareIni(orgContent, destContent, origin, dest, verbose)
// if error occur, try to make a basic diff
Expand All @@ -109,7 +111,7 @@ func CompareFiles(origin string, dest string, print bool, verbose bool) ([]strin
dest, " try to compare as a standard type...")
report, _ = CompareRawData(orgContent, destContent, origin, dest)
}
} else if isJson(orgContent) && isJson(destContent) {
} else if common.IsJson(orgContent) && common.IsJson(destContent) {
log.Info("Files detected as JSON files, start to process contents")
report, err = CompareJSONFiles(orgContent, destContent)
if err != nil {
Expand All @@ -119,7 +121,7 @@ func CompareFiles(origin string, dest string, print bool, verbose bool) ([]strin
dest, " try to compare as a standard type...")
report, _ = CompareRawData(orgContent, destContent, origin, dest)
}
} else if isYaml(orgContent) && isYaml(destContent) {
} else if common.IsYaml(orgContent) && common.IsYaml(destContent) {
log.Info("Files detected as YAML files, start to process contents")
report, err = CompareYAML(orgContent, destContent)
if err != nil {
Expand All @@ -136,7 +138,7 @@ func CompareFiles(origin string, dest string, print bool, verbose bool) ([]strin
}
filePath := origin + ".diff"
if len(report) != 0 {
err = writeReport(report, filePath)
err = WriteReport(report, filePath)
if err != nil {
log.Error("Error while trying to create diff file in the file system: ", filePath)
fmt.Println(err)
Expand Down

0 comments on commit a47d82e

Please sign in to comment.