package subscription import ( "testing" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" "github.com/thrasher-corp/gocryptotrader/currency" "github.com/thrasher-corp/gocryptotrader/exchanges/asset" "github.com/thrasher-corp/gocryptotrader/exchanges/kline" ) // DummyKey is a test key type that ensures that cross compatible keys can be used // It will panic if Match() is called type DummyKey struct { *Subscription detonator testing.TB } var _ MatchableKey = DummyKey{} // Enforce DummyKey must implement MatchableKey // GetSubscription returns the underlying subscription func (k DummyKey) GetSubscription() *Subscription { return k.Subscription } // Match implements MatchableKey func (k DummyKey) Match(_ MatchableKey) bool { k.detonator.Fatal("DummyKey Match should never be called") return false } // TestExactKeyMatch exercises ExactKey.Match func TestExactKeyMatch(t *testing.T) { t.Parallel() key := &ExactKey{&Subscription{Channel: TickerChannel}} try := &DummyKey{&Subscription{Channel: OrderbookChannel}, t} require.False(t, key.Match(nil), "Match on a nil must return false") require.False(t, key.Match(try), "Gate 1: Match must reject a bad Channel") try.Channel = TickerChannel require.True(t, key.Match(try), "Gate 1: Match must accept a good Channel") key.Asset = asset.Spot require.False(t, key.Match(try), "Gate 2: Match must reject a bad Asset") try.Asset = asset.Spot require.True(t, key.Match(try), "Gate 2: Match must accept a good Asset") key.Pairs = currency.Pairs{btcusdtPair} require.False(t, key.Match(try), "Gate 3: Match must reject B empty Pairs when key has Pairs") try.Pairs = currency.Pairs{btcusdtPair} key.Pairs = nil require.False(t, key.Match(try), "Gate 3: Match must reject B has Pairs when key has empty Pairs") key.Pairs = currency.Pairs{btcusdtPair} require.True(t, key.Match(try), "Gate 3: Match must accept matching pairs") key.Pairs = currency.Pairs{ethusdcPair} require.False(t, key.Match(try), "Gate 3: Match must reject when key.Pairs not matching") try.Pairs = currency.Pairs{btcusdtPair, ethusdcPair} require.False(t, key.Match(try), "Gate 3: Match must reject when key.Pairs is only a subset") key.Pairs = currency.Pairs{ethusdcPair, btcusdtPair} require.True(t, key.Match(try), "Gate 3: Match accept when Pairs match in different order") key.Levels = 4 require.False(t, key.Match(try), "Gate 4: Match must reject a bad Level") try.Levels = 4 require.True(t, key.Match(try), "Gate 4: Match must accept a good Level") key.Interval = kline.FiveMin require.False(t, key.Match(try), "Gate 5: Match must reject a bad Interval") try.Interval = kline.FiveMin require.True(t, key.Match(try), "Gate 5: Match must accept a good Interval") } // TestExactKeyString exercises ExactKey.String func TestExactKeyString(t *testing.T) { t.Parallel() key := &ExactKey{} assert.Equal(t, "Uninitialised ExactKey", key.String()) key = &ExactKey{&Subscription{Asset: asset.Spot, Channel: TickerChannel, Pairs: currency.Pairs{ethusdcPair, btcusdtPair}}} assert.Equal(t, "ticker spot ETH/USDC,BTC/USDT", key.String()) } // TestIgnoringPairsKeyMatch exercises IgnoringPairsKey.Match func TestIgnoringPairsKeyMatch(t *testing.T) { t.Parallel() key := &IgnoringPairsKey{&Subscription{Channel: TickerChannel, Pairs: currency.Pairs{btcusdtPair}}} try := &DummyKey{&Subscription{Channel: OrderbookChannel, Pairs: currency.Pairs{ethusdcPair}}, t} require.False(t, key.Match(nil), "Match on a nil must return false") require.False(t, key.Match(try), "Gate 1: Match must reject a bad Channel") try.Channel = TickerChannel require.True(t, key.Match(try), "Gate 1: Match must accept a good Channel") key.Asset = asset.Spot require.False(t, key.Match(try), "Gate 2: Match must reject a bad Asset") try.Asset = asset.Spot require.True(t, key.Match(try), "Gate 2: Match must accept a good Asset") key.Levels = 4 require.False(t, key.Match(try), "Gate 3: Match must reject a bad Level") try.Levels = 4 require.True(t, key.Match(try), "Gate 3: Match must accept a good Level") key.Interval = kline.FiveMin require.False(t, key.Match(try), "Gate 4: Match must reject a bad Interval") try.Interval = kline.FiveMin require.True(t, key.Match(try), "Gate 4: Match must accept a good Interval") } // TestIgnoringPairsKeyString exercises IgnoringPairsKey.String func TestIgnoringPairsKeyString(t *testing.T) { t.Parallel() assert.Equal(t, "Uninitialised IgnoringPairsKey", IgnoringPairsKey{}.String()) key := &IgnoringPairsKey{&Subscription{Asset: asset.Spot, Channel: TickerChannel, Pairs: currency.Pairs{ethusdcPair, btcusdtPair}}} assert.Equal(t, "ticker spot", key.String()) } // TestIgnoringAssetKeyMatch exercises IgnoringAssetKey.Match func TestIgnoringAssetKeyMatch(t *testing.T) { t.Parallel() key := &IgnoringAssetKey{&Subscription{Channel: TickerChannel, Asset: asset.Spot}} try := &DummyKey{&Subscription{Channel: OrderbookChannel}, t} require.False(t, key.Match(nil), "Match on a nil must return false") require.False(t, key.Match(try), "Gate 1: Match must reject a bad Channel") try.Channel = TickerChannel require.True(t, key.Match(try), "Gate 1: Match must accept a good Channel") key.Pairs = currency.Pairs{btcusdtPair} require.False(t, key.Match(try), "Gate 2: Match must reject bad Pairs") try.Pairs = currency.Pairs{btcusdtPair} require.True(t, key.Match(try), "Gate 2: Match must accept a good Pairs") key.Levels = 4 require.False(t, key.Match(try), "Gate 3: Match must reject a bad Level") try.Levels = 4 require.True(t, key.Match(try), "Gate 3: Match must accept a good Level") key.Interval = kline.FiveMin require.False(t, key.Match(try), "Gate 4: Match must reject a bad Interval") try.Interval = kline.FiveMin require.True(t, key.Match(try), "Gate 4: Match must accept a good Interval") } // TestIgnoringAssetKeyString exercises IgnoringAssetKey.String func TestIgnoringAssetKeyString(t *testing.T) { t.Parallel() assert.Equal(t, "Uninitialised IgnoringAssetKey", IgnoringAssetKey{}.String()) key := &IgnoringAssetKey{&Subscription{Asset: asset.Spot, Channel: TickerChannel, Pairs: currency.Pairs{ethusdcPair, btcusdtPair}}} assert.Equal(t, "ticker [ETHUSDC BTCUSDT]", key.String()) } // TestGetSubscription exercises GetSubscription func TestGetSubscription(t *testing.T) { t.Parallel() s := &Subscription{Asset: asset.Spot} assert.Same(t, s, ExactKey{s}.GetSubscription(), "ExactKey.GetSubscription Must return a pointer to the subscription") assert.Same(t, s, IgnoringPairsKey{s}.GetSubscription(), "IgnorePairKeys.GetSubscription Must return a pointer to the subscription") }