Skip to content

Commit 5d4c5cc

Browse files
committed
wip
1 parent f16a077 commit 5d4c5cc

File tree

6 files changed

+347
-6
lines changed

6 files changed

+347
-6
lines changed

and.go

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package comver
22

3+
import "slices"
4+
35
const (
46
ErrNotEnoughEndless stringError = "not enough endless"
57
ErrUnpextedAnd stringError = "unexpected and"
@@ -12,14 +14,19 @@ func And(es ...Endless) (CeilingFloorConstrainter, error) {
1214
return c, ErrNotEnoughEndless
1315
}
1416

15-
if len(es) == 1 {
16-
return es[0], nil
17-
}
17+
es = slices.Clone(es)
18+
es = slices.DeleteFunc(es, func(e Endless) bool {
19+
return e.wildcard()
20+
})
1821

19-
if containsWildcard(es...) {
22+
if len(es) == 0 {
2023
return NewWildcard(), nil
2124
}
2225

26+
if len(es) == 1 {
27+
return es[0], nil
28+
}
29+
2330
floor, floorOk := maxBoundedFloor(es)
2431
ceiling, ceilingOk := minBoundedCeiling(es)
2532

@@ -53,6 +60,7 @@ func And(es ...Endless) (CeilingFloorConstrainter, error) {
5360
return NewExactConstraint(*floor.Floor().version), nil
5461
}
5562

63+
// TODO: Test this return statement!!!!!
5664
return Interval{
5765
ceiling: ceiling,
5866
floor: floor,

and_test.go

Lines changed: 315 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,315 @@
1+
package comver
2+
3+
import (
4+
"errors"
5+
"math/rand/v2"
6+
"reflect"
7+
"testing"
8+
)
9+
10+
func TestAnd(t *testing.T) {
11+
t.Parallel()
12+
13+
tests := []struct {
14+
name string
15+
es []Endless
16+
want CeilingFloorConstrainter
17+
wantErr error
18+
}{
19+
{
20+
name: "empty",
21+
es: []Endless{},
22+
want: NewWildcard(),
23+
wantErr: ErrNotEnoughEndless,
24+
},
25+
{
26+
name: "single_lessThan",
27+
es: []Endless{NewLessThan(MustParse("1"))},
28+
want: NewLessThan(MustParse("1")),
29+
wantErr: nil,
30+
},
31+
{
32+
name: "single_lessThanOrEqualTo",
33+
es: []Endless{NewLessThanOrEqualTo(MustParse("2"))},
34+
want: NewLessThanOrEqualTo(MustParse("2")),
35+
wantErr: nil,
36+
},
37+
{
38+
name: "single_greaterThan",
39+
es: []Endless{NewGreaterThan(MustParse("3"))},
40+
want: NewGreaterThan(MustParse("3")),
41+
wantErr: nil,
42+
},
43+
{
44+
name: "single_greaterThanOrEqualTo",
45+
es: []Endless{NewGreaterThanOrEqualTo(MustParse("4"))},
46+
want: NewGreaterThanOrEqualTo(MustParse("4")),
47+
wantErr: nil,
48+
},
49+
{
50+
name: "single_wildcard",
51+
es: []Endless{NewWildcard()},
52+
want: NewWildcard(),
53+
wantErr: nil,
54+
},
55+
{
56+
name: "multiple_wildcards",
57+
es: []Endless{NewWildcard(), NewWildcard()},
58+
want: NewWildcard(),
59+
wantErr: nil,
60+
},
61+
{
62+
name: "multiple_ceiling_inclusive",
63+
es: []Endless{
64+
NewLessThan(MustParse("1")),
65+
NewLessThanOrEqualTo(MustParse("1")),
66+
NewLessThan(MustParse("2")),
67+
NewLessThanOrEqualTo(MustParse("2")),
68+
},
69+
want: NewLessThan(MustParse("1")),
70+
wantErr: nil,
71+
},
72+
{
73+
name: "multiple_ceiling_non_inclusive",
74+
es: []Endless{
75+
NewLessThan(MustParse("1")),
76+
NewLessThanOrEqualTo(MustParse("1")),
77+
NewLessThan(MustParse("2")),
78+
NewLessThanOrEqualTo(MustParse("2")),
79+
},
80+
want: NewLessThan(MustParse("1")),
81+
wantErr: nil,
82+
},
83+
{
84+
name: "multiple_floors_inclusive",
85+
es: []Endless{
86+
NewGreaterThanOrEqualTo(MustParse("3")),
87+
NewGreaterThan(MustParse("3")),
88+
NewGreaterThanOrEqualTo(MustParse("4")),
89+
},
90+
want: NewGreaterThanOrEqualTo(MustParse("4")),
91+
wantErr: nil,
92+
},
93+
{
94+
name: "multiple_floors_non_inclusive",
95+
es: []Endless{
96+
NewGreaterThanOrEqualTo(MustParse("3")),
97+
NewGreaterThan(MustParse("3")),
98+
NewGreaterThanOrEqualTo(MustParse("4")),
99+
NewGreaterThan(MustParse("4")),
100+
},
101+
want: NewGreaterThan(MustParse("4")),
102+
wantErr: nil,
103+
},
104+
{
105+
name: "impossible_interval",
106+
es: []Endless{
107+
NewLessThan(MustParse("1")),
108+
NewGreaterThan(MustParse("4")),
109+
},
110+
want: NewWildcard(),
111+
wantErr: ErrImpossibleInterval,
112+
},
113+
{
114+
name: "impossible_interval_wildcard",
115+
es: []Endless{
116+
NewLessThan(MustParse("1")),
117+
NewGreaterThan(MustParse("4")),
118+
NewWildcard(),
119+
},
120+
want: NewWildcard(),
121+
wantErr: ErrImpossibleInterval,
122+
},
123+
{
124+
name: "multiple_wildcards_multiple_endlesses",
125+
es: []Endless{
126+
NewLessThan(MustParse("1")),
127+
NewLessThanOrEqualTo(MustParse("1")),
128+
NewLessThan(MustParse("2")),
129+
NewLessThanOrEqualTo(MustParse("2")),
130+
NewGreaterThanOrEqualTo(MustParse("3")),
131+
NewGreaterThan(MustParse("3")),
132+
NewGreaterThanOrEqualTo(MustParse("4")),
133+
NewGreaterThan(MustParse("4")),
134+
NewWildcard(),
135+
NewWildcard(),
136+
},
137+
want: NewWildcard(),
138+
wantErr: ErrImpossibleInterval,
139+
},
140+
{
141+
name: "impossible_interval_same_version",
142+
es: []Endless{
143+
NewLessThan(MustParse("1")),
144+
NewGreaterThan(MustParse("1")),
145+
},
146+
want: NewWildcard(),
147+
wantErr: ErrImpossibleInterval,
148+
},
149+
150+
{
151+
name: "exact_version_ceiling_inclusive",
152+
es: []Endless{
153+
NewLessThanOrEqualTo(MustParse("1")),
154+
NewGreaterThan(MustParse("1")),
155+
},
156+
want: NewExactConstraint(MustParse("1")),
157+
wantErr: nil,
158+
},
159+
{
160+
name: "exact_version_floor_inclusive",
161+
es: []Endless{
162+
NewLessThan(MustParse("1")),
163+
NewGreaterThanOrEqualTo(MustParse("1")),
164+
},
165+
want: NewExactConstraint(MustParse("1")),
166+
wantErr: nil,
167+
},
168+
{
169+
name: "exact_version_ceiling_inclusive_floor_inclusive",
170+
es: []Endless{
171+
NewLessThanOrEqualTo(MustParse("1")),
172+
NewGreaterThanOrEqualTo(MustParse("1")),
173+
},
174+
want: NewExactConstraint(MustParse("1")),
175+
wantErr: nil,
176+
},
177+
{
178+
name: "exact_version_wildcard",
179+
es: []Endless{
180+
NewLessThanOrEqualTo(MustParse("1")),
181+
NewGreaterThanOrEqualTo(MustParse("1")),
182+
NewWildcard(),
183+
},
184+
want: NewExactConstraint(MustParse("1")),
185+
wantErr: nil,
186+
},
187+
{
188+
name: "impossible_interval_same_version",
189+
es: []Endless{
190+
NewLessThanOrEqualTo(MustParse("1")),
191+
NewLessThanOrEqualTo(MustParse("1")),
192+
NewLessThan(MustParse("1")),
193+
NewLessThan(MustParse("1")),
194+
NewGreaterThanOrEqualTo(MustParse("1")),
195+
NewGreaterThanOrEqualTo(MustParse("1")),
196+
NewGreaterThan(MustParse("1")),
197+
NewGreaterThan(MustParse("1")),
198+
NewWildcard(),
199+
NewWildcard(),
200+
},
201+
want: NewWildcard(),
202+
wantErr: ErrImpossibleInterval,
203+
},
204+
{
205+
name: "impossible_interval_same_version",
206+
es: []Endless{
207+
NewLessThan(MustParse("1")),
208+
NewLessThan(MustParse("1")),
209+
NewGreaterThanOrEqualTo(MustParse("1")),
210+
NewGreaterThanOrEqualTo(MustParse("1")),
211+
NewGreaterThan(MustParse("1")),
212+
NewGreaterThan(MustParse("1")),
213+
NewWildcard(),
214+
NewWildcard(),
215+
},
216+
want: NewWildcard(),
217+
wantErr: ErrImpossibleInterval,
218+
},
219+
{
220+
name: "exact_version_multiple",
221+
es: []Endless{
222+
NewLessThanOrEqualTo(MustParse("1")),
223+
NewLessThanOrEqualTo(MustParse("1")),
224+
NewGreaterThanOrEqualTo(MustParse("1")),
225+
NewGreaterThanOrEqualTo(MustParse("1")),
226+
NewGreaterThan(MustParse("1")),
227+
NewGreaterThan(MustParse("1")),
228+
NewWildcard(),
229+
NewWildcard(),
230+
},
231+
want: NewExactConstraint(MustParse("1")),
232+
wantErr: nil,
233+
},
234+
{
235+
name: "impossible_interval_same_version",
236+
es: []Endless{
237+
NewLessThanOrEqualTo(MustParse("1")),
238+
NewLessThanOrEqualTo(MustParse("1")),
239+
NewLessThan(MustParse("1")),
240+
NewLessThan(MustParse("1")),
241+
NewGreaterThan(MustParse("1")),
242+
NewGreaterThan(MustParse("1")),
243+
NewWildcard(),
244+
NewWildcard(),
245+
},
246+
want: NewWildcard(),
247+
wantErr: ErrImpossibleInterval,
248+
},
249+
{
250+
name: "exact_version_multiple",
251+
es: []Endless{
252+
NewLessThanOrEqualTo(MustParse("1")),
253+
NewLessThanOrEqualTo(MustParse("1")),
254+
NewLessThan(MustParse("1")),
255+
NewLessThan(MustParse("1")),
256+
NewGreaterThanOrEqualTo(MustParse("1")),
257+
NewGreaterThanOrEqualTo(MustParse("1")),
258+
NewWildcard(),
259+
NewWildcard(),
260+
},
261+
want: NewExactConstraint(MustParse("1")),
262+
wantErr: nil,
263+
},
264+
{
265+
name: "impossible_interval_same_version",
266+
es: []Endless{
267+
NewLessThanOrEqualTo(MustParse("1")),
268+
NewLessThanOrEqualTo(MustParse("1")),
269+
NewLessThan(MustParse("1")),
270+
NewLessThan(MustParse("1")),
271+
NewGreaterThanOrEqualTo(MustParse("1")),
272+
NewGreaterThanOrEqualTo(MustParse("1")),
273+
NewGreaterThan(MustParse("1")),
274+
NewGreaterThan(MustParse("1")),
275+
},
276+
want: NewWildcard(),
277+
wantErr: ErrImpossibleInterval,
278+
},
279+
}
280+
for _, tt := range tests {
281+
t.Run(tt.name, func(t *testing.T) {
282+
t.Parallel()
283+
284+
rand.Shuffle(len(tt.es), func(i, j int) {
285+
tt.es[i], tt.es[j] = tt.es[j], tt.es[i]
286+
})
287+
288+
got, err := And(tt.es...)
289+
290+
if !errors.Is(err, tt.wantErr) {
291+
t.Fatalf("And() error = %#v, wantErr %#v", err, tt.wantErr)
292+
}
293+
294+
if err != nil {
295+
return
296+
}
297+
298+
if !reflect.DeepEqual(got, tt.want) {
299+
t.Errorf("And() got = %v, want %v", got, tt.want)
300+
}
301+
})
302+
}
303+
304+
t.Run("no_arg", func(t *testing.T) {
305+
t.Parallel()
306+
307+
wantErr := ErrNotEnoughEndless
308+
309+
_, err := And()
310+
311+
if !errors.Is(err, wantErr) {
312+
t.Errorf("And() error = %#v, wantErr %#v", err, wantErr)
313+
}
314+
})
315+
}

ceilinger.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@ type ceilinger interface {
77
}
88

99
func minBoundedCeiling[S ~[]T, T ceilinger](cs S) (T, bool) {
10+
cs = slices.Clone(cs)
11+
1012
bcs := slices.DeleteFunc(cs, func(b T) bool {
1113
return b.Ceiling().version == nil
1214
})

0 commit comments

Comments
 (0)