Skip to content

Commit

Permalink
Cleaning
Browse files Browse the repository at this point in the history
  • Loading branch information
teivah committed Feb 15, 2020
1 parent 684201f commit 45dd9ca
Show file tree
Hide file tree
Showing 37 changed files with 200 additions and 7,087 deletions.
File renamed without changes.
339 changes: 41 additions & 298 deletions assert.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,342 +2,85 @@ package rxgo

import (
"context"
"errors"
"testing"
"time"

"github.com/stretchr/testify/assert"
"testing"
)

const testWaitTime = 30 * time.Millisecond

// RxAssertion lists the assertions which may be configured on an Observable.
type RxAssertion interface {
apply(*assertion)
hasItemsFunc() (bool, []interface{})
hasItemsNoOrderFunc() (bool, []interface{})
hasSizeFunc() (bool, int)
hasValueFunc() (bool, interface{})
hasRaisedErrorFunc() (bool, error)
hasRaisedAnErrorFunc() bool
hasNotRaisedAnErrorFunc() bool
isEmptyFunc() (bool, bool)
}

type assertion struct {
f func(*assertion)
checkHasItems bool
hasItems []interface{}
checkHasItemsNoOrder bool
hasItemsNoOrder []interface{}
checkHasSize bool
hasSize int
checkHasValue bool
hasValue interface{}
checkHasRaisedError bool
hasRaisedError error
checkHasRaisedAnError bool
checkHasNotRaisedAnError bool
checkIsEmpty bool
isEmpty bool
}

func (ass *assertion) hasItemsFunc() (bool, []interface{}) {
return ass.checkHasItems, ass.hasItems
}

func (ass *assertion) hasItemsNoOrderFunc() (bool, []interface{}) {
return ass.checkHasItemsNoOrder, ass.hasItemsNoOrder
}

func (ass *assertion) hasSizeFunc() (bool, int) {
return ass.checkHasSize, ass.hasSize
}

func (ass *assertion) hasValueFunc() (bool, interface{}) {
return ass.checkHasValue, ass.hasValue
type rxAssert interface {
apply(*rxAssertImpl)
hasItemsF() (bool, []interface{})
hasRaisedError() (bool, error)
}

func (ass *assertion) hasRaisedErrorFunc() (bool, error) {
return ass.checkHasRaisedError, ass.hasRaisedError
type rxAssertImpl struct {
f func(*rxAssertImpl)
checkHasItems bool
hasItems []interface{}
checkHasRaisedError bool
hasError error
}

func (ass *assertion) hasRaisedAnErrorFunc() bool {
return ass.checkHasRaisedAnError
}

func (ass *assertion) hasNotRaisedAnErrorFunc() bool {
return ass.checkHasNotRaisedAnError
func (ass *rxAssertImpl) apply(do *rxAssertImpl) {
ass.f(do)
}

func (ass *assertion) isEmptyFunc() (bool, bool) {
return ass.checkIsEmpty, ass.isEmpty
func (ass *rxAssertImpl) hasItemsF() (bool, []interface{}) {
return ass.checkHasItems, ass.hasItems
}

func (ass *assertion) apply(do *assertion) {
ass.f(do)
func (ass *rxAssertImpl) hasRaisedError() (bool, error) {
return ass.checkHasRaisedError, ass.hasError
}

func newAssertion(f func(*assertion)) *assertion {
return &assertion{
func newAssertion(f func(*rxAssertImpl)) *rxAssertImpl {
return &rxAssertImpl{
f: f,
}
}

func parseAssertions(assertions ...RxAssertion) RxAssertion {
a := new(assertion)
for _, assertion := range assertions {
assertion.apply(a)
}
return a
}

// HasItems checks that an observable produces the corresponding items.
func HasItems(items ...interface{}) RxAssertion {
return newAssertion(func(a *assertion) {
func hasItems(items ...interface{}) rxAssert {
return newAssertion(func(a *rxAssertImpl) {
a.checkHasItems = true
a.hasItems = items
})
}

// HasItemsNoOrder checks that an observable produces the corresponding items regardless of the order.
func HasItemsNoOrder(items ...interface{}) RxAssertion {
return newAssertion(func(a *assertion) {
a.checkHasItemsNoOrder = true
a.hasItemsNoOrder = items
})
}

// HasSize checks that an observable produces the corresponding number of items.
func HasSize(size int) RxAssertion {
return newAssertion(func(a *assertion) {
a.checkHasSize = true
a.hasSize = size
})
}

// IsEmpty checks that an observable produces zero items.
func IsEmpty() RxAssertion {
return newAssertion(func(a *assertion) {
a.checkIsEmpty = true
a.isEmpty = true
})
}

// IsNotEmpty checks that an observable produces items.
func IsNotEmpty() RxAssertion {
return newAssertion(func(a *assertion) {
a.checkIsEmpty = true
a.isEmpty = false
})
}

// HasValue checks that a single produces the corresponding value.
func HasValue(value interface{}) RxAssertion {
return newAssertion(func(a *assertion) {
a.checkHasValue = true
a.hasValue = value
})
}

// HasRaisedError checks that a single raises the corresponding error.
func HasRaisedError(err error) RxAssertion {
return newAssertion(func(a *assertion) {
func hasRaisedError(err error) rxAssert {
return newAssertion(func(a *rxAssertImpl) {
a.checkHasRaisedError = true
a.hasRaisedError = err
})
}

// HasRaisedAnError checks that a single raises an error.
func HasRaisedAnError() RxAssertion {
return newAssertion(func(a *assertion) {
a.checkHasRaisedAnError = true
a.hasError = err
})
}

// HasNotRaisedAnyError checks that a single does not raise an error.
func HasNotRaisedAnyError() RxAssertion {
return newAssertion(func(a *assertion) {
a.checkHasNotRaisedAnError = true
})
}

func assertObservable(t *testing.T, ass RxAssertion, got []interface{}, err error) {
checkHasItems, items := ass.hasItemsFunc()
if checkHasItems {
assert.Equal(t, items, got)
}

checkHasItemsNoOrder, itemsNoOrder := ass.hasItemsNoOrderFunc()
if checkHasItemsNoOrder {
m := make(map[interface{}]interface{})
for _, v := range itemsNoOrder {
m[v] = nil
}

for _, v := range got {
delete(m, v)
}
assert.Equal(t, 0, len(m))
}

checkHasSize, size := ass.hasSizeFunc()
if checkHasSize {
assert.Equal(t, size, len(got))
}

checkIsEmpty, empty := ass.isEmptyFunc()
if checkIsEmpty {
if empty {
assert.Equal(t, 0, len(got))
} else {
assert.NotEqual(t, 0, len(got))
}
}

checkHasRaisedAnError := ass.hasRaisedAnErrorFunc()
if checkHasRaisedAnError {
assert.NotNil(t, err)
}

checkHasRaisedError, value := ass.hasRaisedErrorFunc()
if checkHasRaisedError {
assert.Equal(t, value, err)
}

checkHasNotRaisedError := ass.hasNotRaisedAnErrorFunc()
if checkHasNotRaisedError {
assert.Nil(t, err)
func parseAssertions(assertions ...rxAssert) rxAssert {
ass := new(rxAssertImpl)
for _, assertion := range assertions {
assertion.apply(ass)
}
return ass
}

// AssertObservable asserts the result of an Observable against a list of assertions.
func AssertObservable(t *testing.T, observable Observable, assertions ...RxAssertion) {
func assertObservable(t *testing.T, ctx context.Context, observable Observable, assertions ...rxAssert) {
ass := parseAssertions(assertions...)
got := make([]interface{}, 0)
var err error
observable.ForEach(func(i interface{}) {
got = append(got, i)
}, func(e error) {
err = e
}, nil).Block()
assertObservable(t, ass, got, err)
}

// AssertObservableEventually asserts eventually the result of an Observable against a list of assertions.
func AssertObservableEventually(t *testing.T, observable Observable, timeout time.Duration, assertions ...RxAssertion) {
ass := parseAssertions(assertions...)

chItem := make(chan interface{}, 1)
defer close(chItem)
chErr := make(chan error)
defer close(chErr)

got := make([]interface{}, 0)
var err error
done := make(chan struct{})

observable.ForEach(func(i interface{}) {
chItem <- i
observable.ForEach(ctx, func(i interface{}) {
got = append(got, i)
}, func(e error) {
chErr <- e
}, nil)
ctxTimeout, ctxTimeoutF := context.WithTimeout(context.Background(), timeout)
defer ctxTimeoutF()

mainLoop:
for {
select {
case item, open := <-chItem:
if open {
got = append(got, item)
} else {
break mainLoop
}
case e := <-chErr:
err = e
case <-ctxTimeout.Done():
break mainLoop
}
}

assertObservable(t, ass, got, err)
}

// AssertSingle asserts the result of a Single against a list of assertions.
func AssertSingle(t *testing.T, single Single, assertions ...RxAssertion) {
ass := parseAssertions(assertions...)

var v interface{}
var err error
single.Subscribe(NewObserver(NextFunc(func(i interface{}) {
v = i
}), ErrFunc(func(e error) {
err = e
}))).Block()

checkHasValue, value := ass.hasValueFunc()
if checkHasValue {
assert.NoError(t, err)
assert.Equal(t, value, v)
}

checkHasRaisedAnError := ass.hasRaisedAnErrorFunc()
if checkHasRaisedAnError {
assert.NotNil(t, err)
}

checkHasRaisedError, value := ass.hasRaisedErrorFunc()
if checkHasRaisedError {
assert.Equal(t, value, err)
}
}, func() {
close(done)
})

checkHasNotRaisedError := ass.hasNotRaisedAnErrorFunc()
if checkHasNotRaisedError {
assert.Nil(t, err)
if checkHasItems, expectedItems := ass.hasItemsF(); checkHasItems {
<-done
assert.Equal(t, expectedItems, got)
}
}

// AssertOptionalSingle asserts the result of an OptionalSingle against a list of assertions.
func AssertOptionalSingle(t *testing.T, optionalSingle OptionalSingle, assertions ...RxAssertion) {
ass := parseAssertions(assertions...)

var v interface{}
var err error
optionalSingle.Subscribe(NewObserver(NextFunc(func(i interface{}) {
v = i
}), ErrFunc(func(e error) {
err = e
}))).Block()
assert.NoError(t, err)

if optional, ok := v.(Optional); ok {
checkIsEmpty, empty := ass.isEmptyFunc()
if checkIsEmpty {
if empty {
assert.True(t, optional.IsEmpty())
} else {
assert.False(t, optional.IsEmpty())
}
}

got, emptyError := optional.Get()

checkHasRaisedAnError := ass.hasRaisedAnErrorFunc()
if checkHasRaisedAnError {
assert.Nil(t, emptyError)
assert.IsType(t, errors.New(""), got)
}

checkHasRaisedError, emptyError := ass.hasRaisedErrorFunc()
if checkHasRaisedError {
assert.Equal(t, emptyError, got)
}

checkHasValue, value := ass.hasValueFunc()
if checkHasValue {
assert.Equal(t, value, got)
}
} else {
assert.Fail(t, "OptionalSingle did not produce an Optional")
if checkHasRaisedError, expectedError := ass.hasRaisedError(); checkHasRaisedError {
assert.Equal(t, expectedError, err)
}
}
Loading

0 comments on commit 45dd9ca

Please sign in to comment.