Skip to content

Commit 9ba7912

Browse files
author
David Cavazos
committed
add unit tests and testing instructions
1 parent d138552 commit 9ba7912

File tree

13 files changed

+257
-41
lines changed

13 files changed

+257
-41
lines changed

.github/workflows/samples-tools/README.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,15 @@ We can run it in a subshell using parentheses to keep our working directory from
4545
(cd .github/workflows/samples-tools && go build -o /tmp/tools ./cmd/*)
4646
```
4747

48+
## Running the tools unit tests
49+
50+
To the tools tests, we must change to the directory where the tools package is defined.
51+
We can run it in a subshell using parentheses to keep our working directory from changing.
52+
53+
```sh
54+
(cd .github/workflows/samples-tools && go test ./test)
55+
```
56+
4857
## Finding affected packages
4958

5059
> This must run at the repository root directory.

.github/workflows/samples-tools/cmd/main.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -99,12 +99,13 @@ func affectedCmd(configFile string, diffsFile string) {
9999
log.Fatalf("❌ error loading the config file: %v\n%v\n", configFile, err)
100100
}
101101

102-
diffs, err := readDiffs(diffsFile)
102+
diffsBytes, err := os.ReadFile(diffsFile)
103103
if err != nil {
104104
log.Fatalf("❌ error getting the diffs: %v\n%v\n", diffsFile, err)
105105
}
106+
diffs := strings.Split(string(diffsBytes), "\n")
106107

107-
packages, err := affected(config, diffs)
108+
packages, err := utils.Affected(config, diffs)
108109
if err != nil {
109110
log.Fatalf("❌ error finding the affected packages.\n%v\n", err)
110111
}
@@ -136,7 +137,7 @@ func runAllCmd(configFile string, script string) {
136137
}
137138

138139
maxGoroutines := 16
139-
failed := runAll(packages, script, maxGoroutines)
140+
failed := utils.RunAll(packages, script, maxGoroutines)
140141

141142
fmt.Printf(strings.Repeat("-", 80) + "\n")
142143
fmt.Printf("Total tests: %v\n", len(packages))

.github/workflows/samples-tools/cmd/affected.go renamed to .github/workflows/samples-tools/pkg/utils/affected.go

Lines changed: 15 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -14,17 +14,21 @@
1414
limitations under the License.
1515
*/
1616

17-
package main
17+
package utils
1818

1919
import (
20-
"os"
2120
"slices"
22-
"strings"
23-
24-
"samples-tools/pkg/utils"
2521
)
2622

27-
func affected(config utils.Config, diffs []string) ([]string, error) {
23+
func Affected(config Config, diffs []string) ([]string, error) {
24+
changed := Changed(config, diffs)
25+
if slices.Contains(changed, ".") {
26+
return FindAllPackages(".", config)
27+
}
28+
return changed, nil
29+
}
30+
31+
func Changed(config Config, diffs []string) []string {
2832
changedUnique := make(map[string]bool)
2933
for _, diff := range diffs {
3034
if !config.Matches(diff) {
@@ -37,21 +41,13 @@ func affected(config utils.Config, diffs []string) ([]string, error) {
3741
changedUnique[pkg] = true
3842
}
3943

44+
if len(changedUnique) == 0 {
45+
return []string{"."}
46+
}
47+
4048
changed := make([]string, 0, len(changedUnique))
4149
for pkg := range changedUnique {
4250
changed = append(changed, pkg)
4351
}
44-
45-
if slices.Contains(changed, ".") {
46-
return utils.FindAllPackages(".", config)
47-
}
48-
return changed, nil
49-
}
50-
51-
func readDiffs(path string) ([]string, error) {
52-
bytes, err := os.ReadFile(path)
53-
if err != nil {
54-
return []string{}, err
55-
}
56-
return strings.Split(string(bytes), "\n"), nil
52+
return changed
5753
}

.github/workflows/samples-tools/pkg/utils/config.go

Lines changed: 28 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -39,35 +39,47 @@ type Config struct {
3939
ExcludePackages []string `json:"exclude-packages"`
4040
}
4141

42-
var multiLineCommentsRegex = regexp.MustCompile(`(?s)\s*/\*.*?\*/\s*`)
42+
var multiLineCommentsRegex = regexp.MustCompile(`(?s)\s*/\*.*?\*/`)
4343
var singleLineCommentsRegex = regexp.MustCompile(`\s*//.*\s*`)
4444

45-
// LoadConfig loads the config from the given path.
46-
func LoadConfig(path string) (Config, error) {
47-
bytes, err := os.ReadFile(path)
45+
// SaveConfig saves the config to the given file.
46+
func SaveConfig(config Config, file *os.File) error {
47+
bytes, err := json.MarshalIndent(config, "", " ")
4848
if err != nil {
49-
return Config{}, err
49+
return err
5050
}
51-
config, err := parseConfig(bytes)
51+
_, err = file.Write(bytes)
5252
if err != nil {
53-
return Config{}, err
53+
return err
5454
}
55-
return config, nil
55+
return nil
5656
}
5757

58-
// parseConfig parses the config from the given source.
59-
func parseConfig(source []byte) (Config, error) {
60-
var config Config
61-
err := json.Unmarshal(StripComments(source), &config)
58+
// LoadConfig loads the config from the given path.
59+
func LoadConfig(path string) (Config, error) {
60+
config := Config{}
61+
62+
// Read the JSONC file.
63+
sourceJsonc, err := os.ReadFile(path)
6264
if err != nil {
63-
return Config{}, err
65+
return config, err
6466
}
67+
68+
// Strip the comments and load the JSON.
69+
sourceJson := StripComments(sourceJsonc)
70+
err = json.Unmarshal(sourceJson, &config)
71+
if err != nil {
72+
return config, err
73+
}
74+
75+
// Set default values if they are not set.
6576
if config.PackageFile == nil {
6677
return config, errors.New("package-file is required")
6778
}
6879
if config.Match == nil {
6980
config.Match = []string{"*"}
7081
}
82+
7183
return config, nil
7284
}
7385

@@ -77,8 +89,8 @@ func StripComments(src []byte) []byte {
7789
return singleLineCommentsRegex.ReplaceAll(src, []byte{})
7890
}
7991

80-
// match returns true if the path matches any of the patterns.
81-
func match(patterns []string, path string) bool {
92+
// Match returns true if the path matches any of the patterns.
93+
func Match(patterns []string, path string) bool {
8294
filename := filepath.Base(path)
8395
for _, pattern := range patterns {
8496
if match, _ := filepath.Match(pattern, filename); match {
@@ -93,7 +105,7 @@ func match(patterns []string, path string) bool {
93105

94106
// Matches returns true if the path matches the config.
95107
func (c Config) Matches(path string) bool {
96-
return match(c.Match, path) && !match(c.Ignore, path)
108+
return Match(c.Match, path) && !Match(c.Ignore, path)
97109
}
98110

99111
// IsPackageDir returns true if the path is a package directory.

.github/workflows/samples-tools/cmd/runAll.go renamed to .github/workflows/samples-tools/pkg/utils/runAll.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
limitations under the License.
1515
*/
1616

17-
package main
17+
package utils
1818

1919
import (
2020
"fmt"
@@ -24,8 +24,8 @@ import (
2424
"sync/atomic"
2525
)
2626

27-
// runAll runs all the commands in parallel.
28-
func runAll(packages []string, script string, maxGoroutines int) int64 {
27+
// RunAll runs all the commands in parallel.
28+
func RunAll(packages []string, script string, maxGoroutines int) int64 {
2929
var failures int64
3030
guard := make(chan struct{}, maxGoroutines)
3131
for _, pkg := range packages {
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
package test
2+
3+
import (
4+
"path/filepath"
5+
"samples-tools/pkg/utils"
6+
"testing"
7+
)
8+
9+
func TestChangedRoot(t *testing.T) {
10+
config := utils.Config{PackageFile: []string{"package.json"}}
11+
diffs := []string{
12+
filepath.Join("testdata", "file.txt"),
13+
}
14+
got := utils.Changed(config, diffs)
15+
expected := []string{"."}
16+
equals(t, expected, got)
17+
}
18+
19+
func TestChangedPackage(t *testing.T) {
20+
config := utils.Config{
21+
PackageFile: []string{"package.json"},
22+
Match: []string{"*"},
23+
}
24+
diffs := []string{
25+
filepath.Join("testdata", "my-package", "file.txt"),
26+
}
27+
got := utils.Changed(config, diffs)
28+
expected := []string{"testdata/my-package"}
29+
equals(t, expected, got)
30+
}
31+
32+
func TestChangedSubpackage(t *testing.T) {
33+
config := utils.Config{
34+
PackageFile: []string{"package.json"},
35+
Match: []string{"*"},
36+
}
37+
diffs := []string{
38+
filepath.Join("testdata", "my-package", "subpackage", "file.txt"),
39+
}
40+
got := utils.Changed(config, diffs)
41+
expected := []string{"testdata/my-package/subpackage"}
42+
equals(t, expected, got)
43+
}
Lines changed: 98 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,98 @@
1+
package test
2+
3+
import (
4+
"os"
5+
"path/filepath"
6+
"samples-tools/pkg/utils"
7+
"testing"
8+
)
9+
10+
func TestLoadConfigEmpty(t *testing.T) {
11+
path := filepath.Join("testdata", "config", "empty.json")
12+
_, err := utils.LoadConfig(path)
13+
expectError(t, err)
14+
}
15+
16+
func TestLoadConfigDefaultValues(t *testing.T) {
17+
path := filepath.Join("testdata", "config", "default-values.json")
18+
config, err := utils.LoadConfig(path)
19+
ok(t, err)
20+
expected := utils.Config{
21+
PackageFile: []string{"package.json"},
22+
Match: []string{"*"},
23+
}
24+
equals(t, expected, config)
25+
}
26+
27+
func TestLoadConfigComments(t *testing.T) {
28+
path := filepath.Join("testdata", "config", "comments.jsonc")
29+
config, err := utils.LoadConfig(path)
30+
ok(t, err)
31+
expected := utils.Config{
32+
PackageFile: []string{"package.json"},
33+
Match: []string{"*"},
34+
}
35+
equals(t, expected, config)
36+
}
37+
38+
func TestSaveLoadConfig(t *testing.T) {
39+
file, err := os.CreateTemp("", "config-*.json")
40+
ok(t, err)
41+
defer os.Remove(file.Name())
42+
43+
config := utils.Config{
44+
PackageFile: []string{"package.json"},
45+
Ignore: []string{"node_modules/", "*.md"},
46+
Match: []string{"*.js"},
47+
ExcludePackages: []string{"excluded"},
48+
}
49+
err = utils.SaveConfig(config, file)
50+
ok(t, err)
51+
52+
loadedConfig, err := utils.LoadConfig(file.Name())
53+
ok(t, err)
54+
55+
equals(t, config, loadedConfig)
56+
}
57+
58+
func TestMatchNoPatterns(t *testing.T) {
59+
patterns := []string{}
60+
path := "path/to/file.js"
61+
assert(t, !utils.Match(patterns, path), "match(%v, %v) = false")
62+
}
63+
64+
func TestMatchFilePattern(t *testing.T) {
65+
patterns := []string{"*.js"}
66+
path := "path/to/file.js"
67+
assert(t, utils.Match(patterns, path), "match(%v, %v) = true")
68+
}
69+
70+
func TestMatchFilePath(t *testing.T) {
71+
patterns := []string{"path/to/"}
72+
path := "path/to/file.js"
73+
assert(t, utils.Match(patterns, path), "match(%v, %v) = true")
74+
}
75+
76+
func TestIsPackageDirNotExists(t *testing.T) {
77+
config := utils.Config{PackageFile: []string{"package.json"}}
78+
dir := "path-does-not-exist"
79+
assert(t, !config.IsPackageDir(dir), "config.IsPackageDir(%v) = false")
80+
}
81+
82+
func TestIsPackageDirExists(t *testing.T) {
83+
config := utils.Config{PackageFile: []string{"package.json"}}
84+
dir := filepath.Join("testdata", "my-package")
85+
assert(t, config.IsPackageDir(dir), "config.IsPackageDir(%v) = true")
86+
}
87+
88+
func TestFindPackageRoot(t *testing.T) {
89+
config := utils.Config{PackageFile: []string{"package.json"}}
90+
path := filepath.Join("testdata", "my-file.txt")
91+
equals(t, ".", config.FindPackage(path))
92+
}
93+
94+
func TestFindPackageSubpackage(t *testing.T) {
95+
config := utils.Config{PackageFile: []string{"package.json"}}
96+
path := filepath.Join("testdata", "my-package", "subpackage", "my-file.txt")
97+
equals(t, "testdata/my-package/subpackage", config.FindPackage(path))
98+
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
/*
2+
* Multi-line
3+
* comment
4+
*/
5+
{
6+
// Single line comment.
7+
"package-file": /* inline comment */ ["package.json"]
8+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"package-file": ["package.json"]
3+
}
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
{}

0 commit comments

Comments
 (0)