Skip to content

Commit 2cc81ae

Browse files
author
Per Goncalves da Silva
committed
Refactor slice utils package structure
Signed-off-by: Per Goncalves da Silva <pegoncal@redhat.com>
1 parent 29547aa commit 2cc81ae

File tree

8 files changed

+285
-271
lines changed

8 files changed

+285
-271
lines changed

internal/catalogmetadata/filter/bundle_predicates.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,10 @@ import (
66
"github.com/operator-framework/operator-registry/alpha/declcfg"
77

88
"github.com/operator-framework/operator-controller/internal/bundleutil"
9-
slicesutil "github.com/operator-framework/operator-controller/internal/util/slices"
9+
filterutil "github.com/operator-framework/operator-controller/internal/util/filter"
1010
)
1111

12-
func InMastermindsSemverRange(semverRange *mmsemver.Constraints) slicesutil.Predicate[declcfg.Bundle] {
12+
func InMastermindsSemverRange(semverRange *mmsemver.Constraints) filterutil.Predicate[declcfg.Bundle] {
1313
return func(b declcfg.Bundle) bool {
1414
bVersion, err := bundleutil.GetVersion(b)
1515
if err != nil {
@@ -27,7 +27,7 @@ func InMastermindsSemverRange(semverRange *mmsemver.Constraints) slicesutil.Pred
2727
}
2828
}
2929

30-
func InAnyChannel(channels ...declcfg.Channel) slicesutil.Predicate[declcfg.Bundle] {
30+
func InAnyChannel(channels ...declcfg.Channel) filterutil.Predicate[declcfg.Bundle] {
3131
return func(bundle declcfg.Bundle) bool {
3232
for _, ch := range channels {
3333
for _, entry := range ch.Entries {

internal/catalogmetadata/filter/successors.go

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,10 @@ import (
99
"github.com/operator-framework/operator-registry/alpha/declcfg"
1010

1111
ocv1 "github.com/operator-framework/operator-controller/api/v1"
12-
slicesutil "github.com/operator-framework/operator-controller/internal/util/slices"
12+
filterutil "github.com/operator-framework/operator-controller/internal/util/filter"
1313
)
1414

15-
func SuccessorsOf(installedBundle ocv1.BundleMetadata, channels ...declcfg.Channel) (slicesutil.Predicate[declcfg.Bundle], error) {
15+
func SuccessorsOf(installedBundle ocv1.BundleMetadata, channels ...declcfg.Channel) (filterutil.Predicate[declcfg.Bundle], error) {
1616
installedBundleVersion, err := mmsemver.NewVersion(installedBundle.Version)
1717
if err != nil {
1818
return nil, fmt.Errorf("parsing installed bundle %q version %q: %w", installedBundle.Name, installedBundle.Version, err)
@@ -29,13 +29,13 @@ func SuccessorsOf(installedBundle ocv1.BundleMetadata, channels ...declcfg.Chann
2929
}
3030

3131
// We need either successors or current version (no upgrade)
32-
return slicesutil.Or(
32+
return filterutil.Or(
3333
successorsPredicate,
3434
InMastermindsSemverRange(installedVersionConstraint),
3535
), nil
3636
}
3737

38-
func legacySuccessor(installedBundle ocv1.BundleMetadata, channels ...declcfg.Channel) (slicesutil.Predicate[declcfg.Bundle], error) {
38+
func legacySuccessor(installedBundle ocv1.BundleMetadata, channels ...declcfg.Channel) (filterutil.Predicate[declcfg.Bundle], error) {
3939
installedBundleVersion, err := bsemver.Parse(installedBundle.Version)
4040
if err != nil {
4141
return nil, fmt.Errorf("error parsing installed bundle version: %w", err)

internal/resolve/catalog.go

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import (
2222
"github.com/operator-framework/operator-controller/internal/bundleutil"
2323
"github.com/operator-framework/operator-controller/internal/catalogmetadata/compare"
2424
"github.com/operator-framework/operator-controller/internal/catalogmetadata/filter"
25+
filterutil "github.com/operator-framework/operator-controller/internal/util/filter"
2526
slicesutil "github.com/operator-framework/operator-controller/internal/util/slices"
2627
)
2728

@@ -76,7 +77,7 @@ func (r *CatalogResolver) Resolve(ctx context.Context, ext *ocv1.ClusterExtensio
7677

7778
var catStats []*catStat
7879

79-
resolvedBundles := []foundBundle{}
80+
var resolvedBundles []foundBundle
8081
var priorDeprecation *declcfg.Deprecation
8182

8283
listOptions := []client.ListOption{
@@ -97,7 +98,7 @@ func (r *CatalogResolver) Resolve(ctx context.Context, ext *ocv1.ClusterExtensio
9798
cs.PackageFound = true
9899
cs.TotalBundles = len(packageFBC.Bundles)
99100

100-
var predicates []slicesutil.Predicate[declcfg.Bundle]
101+
var predicates []filterutil.Predicate[declcfg.Bundle]
101102
if len(channels) > 0 {
102103
channelSet := sets.New(channels...)
103104
filteredChannels := slices.DeleteFunc(packageFBC.Channels, func(c declcfg.Channel) bool {
@@ -119,7 +120,7 @@ func (r *CatalogResolver) Resolve(ctx context.Context, ext *ocv1.ClusterExtensio
119120
}
120121

121122
// Apply the predicates to get the candidate bundles
122-
packageFBC.Bundles = slicesutil.RemoveInPlace(packageFBC.Bundles, slicesutil.And(predicates...))
123+
packageFBC.Bundles = slicesutil.RemoveInPlace(packageFBC.Bundles, filterutil.And(predicates...))
123124
cs.MatchedBundles = len(packageFBC.Bundles)
124125
if len(packageFBC.Bundles) == 0 {
125126
return nil

internal/util/slices/filter.go renamed to internal/util/filter/predicates.go

Lines changed: 1 addition & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,8 @@
1-
package slices
2-
3-
import (
4-
"slices"
5-
)
1+
package filter
62

73
// Predicate returns true if the object should be kept when filtering
84
type Predicate[T any] func(entity T) bool
95

10-
// Filter creates a new slice with all elements from s for which the test returns true
11-
func Filter[T any](s []T, test Predicate[T]) []T {
12-
out := make([]T, 0, len(s))
13-
for i := 0; i < len(s); i++ {
14-
if test(s[i]) {
15-
out = append(out, s[i])
16-
}
17-
}
18-
return slices.Clip(out)
19-
}
20-
21-
// RemoveInPlace removes all elements from s for which test returns true.
22-
// Elements between new length and original length are zeroed out.
23-
func RemoveInPlace[T any](s []T, test Predicate[T]) []T {
24-
return slices.DeleteFunc(s, Not(test))
25-
}
26-
276
func And[T any](predicates ...Predicate[T]) Predicate[T] {
287
return func(obj T) bool {
298
for _, predicate := range predicates {
Lines changed: 147 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,147 @@
1+
package filter_test
2+
3+
import (
4+
"testing"
5+
6+
"github.com/stretchr/testify/require"
7+
8+
"github.com/operator-framework/operator-controller/internal/util/filter"
9+
)
10+
11+
func TestAnd(t *testing.T) {
12+
tests := []struct {
13+
name string
14+
predicates []filter.Predicate[int]
15+
input int
16+
want bool
17+
}{
18+
{
19+
name: "all true",
20+
predicates: []filter.Predicate[int]{
21+
func(i int) bool { return i > 0 },
22+
func(i int) bool { return i < 10 },
23+
},
24+
input: 5,
25+
want: true,
26+
},
27+
{
28+
name: "one false",
29+
predicates: []filter.Predicate[int]{
30+
func(i int) bool { return i > 0 },
31+
func(i int) bool { return i < 5 },
32+
},
33+
input: 5,
34+
want: false,
35+
},
36+
{
37+
name: "all false",
38+
predicates: []filter.Predicate[int]{
39+
func(i int) bool { return i > 10 },
40+
func(i int) bool { return i < 0 },
41+
},
42+
input: 5,
43+
want: false,
44+
},
45+
{
46+
name: "no predicates",
47+
predicates: []filter.Predicate[int]{},
48+
input: 5,
49+
want: true,
50+
},
51+
{
52+
name: "nil predicates",
53+
predicates: nil,
54+
input: 5,
55+
want: true,
56+
},
57+
}
58+
for _, tt := range tests {
59+
t.Run(tt.name, func(t *testing.T) {
60+
got := filter.And(tt.predicates...)(tt.input)
61+
require.Equal(t, tt.want, got, "And() = %v, want %v", got, tt.want)
62+
})
63+
}
64+
}
65+
66+
func TestOr(t *testing.T) {
67+
tests := []struct {
68+
name string
69+
predicates []filter.Predicate[int]
70+
input int
71+
want bool
72+
}{
73+
{
74+
name: "all true",
75+
predicates: []filter.Predicate[int]{
76+
func(i int) bool { return i > 0 },
77+
func(i int) bool { return i < 10 },
78+
},
79+
input: 5,
80+
want: true,
81+
},
82+
{
83+
name: "one false",
84+
predicates: []filter.Predicate[int]{
85+
func(i int) bool { return i > 0 },
86+
func(i int) bool { return i < 5 },
87+
},
88+
input: 5,
89+
want: true,
90+
},
91+
{
92+
name: "all false",
93+
predicates: []filter.Predicate[int]{
94+
func(i int) bool { return i > 10 },
95+
func(i int) bool { return i < 0 },
96+
},
97+
input: 5,
98+
want: false,
99+
},
100+
{
101+
name: "no predicates",
102+
predicates: []filter.Predicate[int]{},
103+
input: 5,
104+
want: false,
105+
},
106+
{
107+
name: "nil predicates",
108+
predicates: nil,
109+
input: 5,
110+
want: false,
111+
},
112+
}
113+
for _, tt := range tests {
114+
t.Run(tt.name, func(t *testing.T) {
115+
got := filter.Or(tt.predicates...)(tt.input)
116+
require.Equal(t, tt.want, got, "Or() = %v, want %v", got, tt.want)
117+
})
118+
}
119+
}
120+
121+
func TestNot(t *testing.T) {
122+
tests := []struct {
123+
name string
124+
predicate filter.Predicate[int]
125+
input int
126+
want bool
127+
}{
128+
{
129+
name: "predicate is true",
130+
predicate: func(i int) bool { return i > 0 },
131+
input: 5,
132+
want: false,
133+
},
134+
{
135+
name: "predicate is false",
136+
predicate: func(i int) bool { return i > 3 },
137+
input: 2,
138+
want: true,
139+
},
140+
}
141+
for _, tt := range tests {
142+
t.Run(tt.name, func(t *testing.T) {
143+
got := filter.Not(tt.predicate)(tt.input)
144+
require.Equal(t, tt.want, got, "Not() = %v, want %v", got, tt.want)
145+
})
146+
}
147+
}

0 commit comments

Comments
 (0)