Skip to content

Commit 8f7a17d

Browse files
committed
test(rx): add base rx-assert (#266)
1 parent 7f1fbb1 commit 8f7a17d

File tree

4 files changed

+304
-0
lines changed

4 files changed

+304
-0
lines changed

rx/item.go

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
package rx
2+
3+
type Item[T any] struct{}

rx/iteratable.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
package rx
2+
3+
// Iterable is the basic type that can be observed.
4+
type Iterable[T any] interface {
5+
// Observe(opts ...Option[T]) <-chan Item[T]
6+
}

rx/rx-assert_test.go

Lines changed: 282 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,282 @@
1+
//nolint:gocritic // commented out code
2+
package rx_test
3+
4+
import (
5+
"context"
6+
7+
"github.com/snivilised/extendio/rx"
8+
)
9+
10+
// AssertPredicate is a custom predicate based on the items.
11+
type AssertPredicate[T any] func(items []T) error
12+
13+
// RxAssert[T] lists the Observable assertions.
14+
type RxAssert[T any] interface {
15+
apply(*rxAssert[T])
16+
itemsToBeChecked() (bool, []T)
17+
itemsNoOrderedToBeChecked() (bool, []T)
18+
noItemsToBeChecked() bool
19+
someItemsToBeChecked() bool
20+
raisedErrorToBeChecked() (bool, error)
21+
raisedErrorsToBeChecked() (bool, []error)
22+
raisedAnErrorToBeChecked() (bool, error)
23+
notRaisedErrorToBeChecked() bool
24+
itemToBeChecked() (bool, T)
25+
noItemToBeChecked() (bool, T)
26+
customPredicatesToBeChecked() (bool, []AssertPredicate[T])
27+
}
28+
29+
type rxAssert[T any] struct {
30+
f func(*rxAssert[T])
31+
checkHasItems bool
32+
checkHasNoItems bool
33+
checkHasSomeItems bool
34+
items []T
35+
checkHasItemsNoOrder bool
36+
itemsNoOrder []T
37+
checkHasRaisedError bool
38+
err error
39+
checkHasRaisedErrors bool
40+
errs []error
41+
checkHasRaisedAnError bool
42+
checkHasNotRaisedError bool
43+
checkHasItem bool
44+
item T
45+
checkHasNoItem bool
46+
checkHasCustomPredicate bool
47+
customPredicates []AssertPredicate[T]
48+
}
49+
50+
func (ass *rxAssert[T]) apply(do *rxAssert[T]) {
51+
ass.f(do)
52+
}
53+
54+
func (ass *rxAssert[T]) itemsToBeChecked() (res bool, items []T) {
55+
return ass.checkHasItems, ass.items
56+
}
57+
58+
func (ass *rxAssert[T]) itemsNoOrderedToBeChecked() (res bool, items []T) {
59+
return ass.checkHasItemsNoOrder, ass.itemsNoOrder
60+
}
61+
62+
func (ass *rxAssert[T]) noItemsToBeChecked() bool {
63+
return ass.checkHasNoItems
64+
}
65+
66+
func (ass *rxAssert[T]) someItemsToBeChecked() bool {
67+
return ass.checkHasSomeItems
68+
}
69+
70+
func (ass *rxAssert[T]) raisedErrorToBeChecked() (bool, error) {
71+
return ass.checkHasRaisedError, ass.err
72+
}
73+
74+
func (ass *rxAssert[T]) raisedErrorsToBeChecked() (bool, []error) {
75+
return ass.checkHasRaisedErrors, ass.errs
76+
}
77+
78+
func (ass *rxAssert[T]) raisedAnErrorToBeChecked() (bool, error) {
79+
return ass.checkHasRaisedAnError, ass.err
80+
}
81+
82+
func (ass *rxAssert[T]) notRaisedErrorToBeChecked() bool {
83+
return ass.checkHasNotRaisedError
84+
}
85+
86+
func (ass *rxAssert[T]) itemToBeChecked() (res bool, item T) {
87+
return ass.checkHasItem, ass.item
88+
}
89+
90+
func (ass *rxAssert[T]) noItemToBeChecked() (res bool, item T) {
91+
return ass.checkHasNoItem, ass.item
92+
}
93+
94+
func (ass *rxAssert[T]) customPredicatesToBeChecked() (bool, []AssertPredicate[T]) {
95+
return ass.checkHasCustomPredicate, ass.customPredicates
96+
}
97+
98+
func newAssertion[T any](f func(*rxAssert[T])) *rxAssert[T] {
99+
return &rxAssert[T]{
100+
f: f,
101+
}
102+
}
103+
104+
// HasItems checks that the observable produces the corresponding items.
105+
func HasItems[T any](items ...T) RxAssert[T] {
106+
return newAssertion(func(a *rxAssert[T]) {
107+
a.checkHasItems = true
108+
a.items = items
109+
})
110+
}
111+
112+
// HasItem checks if a single or optional single has a specific item.
113+
func HasItem[T any](i T) RxAssert[T] {
114+
return newAssertion(func(a *rxAssert[T]) {
115+
a.checkHasItem = true
116+
a.item = i
117+
})
118+
}
119+
120+
// HasItemsNoOrder checks that an observable produces the corresponding
121+
// items regardless of the order.
122+
func HasItemsNoOrder[T any](items ...T) RxAssert[T] {
123+
return newAssertion(func(a *rxAssert[T]) {
124+
a.checkHasItemsNoOrder = true
125+
a.itemsNoOrder = items
126+
})
127+
}
128+
129+
// IsNotEmpty checks that the observable produces some items.
130+
func IsNotEmpty[T any]() RxAssert[T] {
131+
return newAssertion(func(a *rxAssert[T]) {
132+
a.checkHasSomeItems = true
133+
})
134+
}
135+
136+
// IsEmpty checks that the observable has not produce any item.
137+
func IsEmpty[T any]() RxAssert[T] {
138+
return newAssertion(func(a *rxAssert[T]) {
139+
a.checkHasNoItems = true
140+
})
141+
}
142+
143+
// HasError checks that the observable has produce a specific error.
144+
func HasError[T any](err error) RxAssert[T] {
145+
return newAssertion(func(a *rxAssert[T]) {
146+
a.checkHasRaisedError = true
147+
a.err = err
148+
})
149+
}
150+
151+
// HasAnError checks that the observable has produce an error.
152+
func HasAnError[T any]() RxAssert[T] {
153+
return newAssertion(func(a *rxAssert[T]) {
154+
a.checkHasRaisedAnError = true
155+
})
156+
}
157+
158+
// HasErrors checks that the observable has produce a set of errors.
159+
func HasErrors[T any](errs ...error) RxAssert[T] {
160+
return newAssertion(func(a *rxAssert[T]) {
161+
a.checkHasRaisedErrors = true
162+
a.errs = errs
163+
})
164+
}
165+
166+
// HasNoError checks that the observable has not raised any error.
167+
func HasNoError[T any]() RxAssert[T] {
168+
return newAssertion(func(a *rxAssert[T]) {
169+
a.checkHasRaisedError = true
170+
})
171+
}
172+
173+
// CustomPredicate checks a custom predicate.
174+
func CustomPredicate[T any](predicate AssertPredicate[T]) RxAssert[T] {
175+
return newAssertion(func(a *rxAssert[T]) {
176+
if !a.checkHasCustomPredicate {
177+
a.checkHasCustomPredicate = true
178+
a.customPredicates = make([]AssertPredicate[T], 0)
179+
}
180+
a.customPredicates = append(a.customPredicates, predicate)
181+
})
182+
}
183+
184+
func parseAssertions[T any](assertions ...RxAssert[T]) RxAssert[T] {
185+
ass := new(rxAssert[T])
186+
for _, assertion := range assertions {
187+
assertion.apply(ass)
188+
}
189+
190+
return ass
191+
}
192+
193+
// Assert asserts the result of an iterable against a list of assertions.
194+
func Assert[T any](_ context.Context, _ rx.Iterable[T], _ ...RxAssert[T]) {
195+
// ass := parseAssertions(assertions...)
196+
197+
// got := make([]interface{}, 0)
198+
// errs := make([]error, 0)
199+
200+
// observe := iterable.Observe()
201+
// loop:
202+
// for {
203+
// select {
204+
// case <-ctx.Done():
205+
// break loop
206+
// case item, ok := <-observe:
207+
// if !ok {
208+
// break loop
209+
// }
210+
// if item.Error() {
211+
// errs = append(errs, item.E)
212+
// } else {
213+
// got = append(got, item.V)
214+
// }
215+
// }
216+
// }
217+
218+
// if checked, predicates := ass.customPredicatesToBeChecked(); checked {
219+
// for _, predicate := range predicates {
220+
// err := predicate(got)
221+
// if err != nil {
222+
// Fail(err.Error())
223+
// }
224+
// }
225+
// }
226+
// if checkHasItems, expectedItems := ass.itemsToBeChecked(); checkHasItems {
227+
// Expect(1).To(Equal(1)) // REMOVE ME
228+
// assert.Equal(t, expectedItems, got)
229+
// }
230+
// if checkHasItemsNoOrder, itemsNoOrder := ass.itemsNoOrderedToBeChecked(); checkHasItemsNoOrder {
231+
// m := make(map[interface{}]interface{})
232+
// for _, v := range itemsNoOrder {
233+
// m[v] = nil
234+
// }
235+
236+
// for _, v := range got {
237+
// delete(m, v)
238+
// }
239+
// if len(m) != 0 {
240+
// assert.Fail(t, "missing elements", "%v", got)
241+
// }
242+
// }
243+
//
244+
// if checkHasItem, value := ass.itemToBeChecked(); checkHasItem {
245+
// length := len(got)
246+
// if length != 1 {
247+
// assert.FailNow(t, "wrong number of items", "expected 1, got %d", length)
248+
// }
249+
// assert.Equal(t, value, got[0])
250+
// }
251+
//
252+
// if ass.noItemsToBeChecked() {
253+
// assert.Equal(t, 0, len(got))
254+
// }
255+
//
256+
// if ass.someItemsToBeChecked() {
257+
// assert.NotEqual(t, 0, len(got))
258+
// }
259+
//
260+
// if checkHasRaisedError, expectedError := ass.raisedErrorToBeChecked(); checkHasRaisedError {
261+
// if expectedError == nil {
262+
// assert.Equal(t, 0, len(errs))
263+
// } else {
264+
// if len(errs) == 0 {
265+
// assert.FailNow(t, "no error raised", "expected %v", expectedError)
266+
// }
267+
// assert.Equal(t, expectedError, errs[0])
268+
// }
269+
// }
270+
//
271+
// if checkHasRaisedErrors, expectedErrors := ass.raisedErrorsToBeChecked(); checkHasRaisedErrors {
272+
// assert.Equal(t, expectedErrors, errs)
273+
// }
274+
//
275+
// if checkHasRaisedAnError, expectedError := ass.raisedAnErrorToBeChecked(); checkHasRaisedAnError {
276+
// assert.Nil(t, expectedError)
277+
// }
278+
//
279+
// if ass.notRaisedErrorToBeChecked() {
280+
// assert.Equal(t, 0, len(errs))
281+
// }
282+
}

rx/rx_suite_test.go

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package rx_test
2+
3+
import (
4+
"testing"
5+
6+
. "github.com/onsi/ginkgo/v2"
7+
. "github.com/onsi/gomega"
8+
)
9+
10+
func TestRx(t *testing.T) {
11+
RegisterFailHandler(Fail)
12+
RunSpecs(t, "Rx Suite")
13+
}

0 commit comments

Comments
 (0)