github.com/cosmos/cosmos-sdk@v0.50.10/types/events_test.go (about) 1 package types_test 2 3 import ( 4 "encoding/json" 5 "reflect" 6 "testing" 7 8 abci "github.com/cometbft/cometbft/abci/types" 9 "github.com/stretchr/testify/suite" 10 11 "cosmossdk.io/math" 12 13 codectypes "github.com/cosmos/cosmos-sdk/codec/types" 14 testdata "github.com/cosmos/cosmos-sdk/testutil/testdata" 15 sdk "github.com/cosmos/cosmos-sdk/types" 16 ) 17 18 type eventsTestSuite struct { 19 suite.Suite 20 } 21 22 func TestEventsTestSuite(t *testing.T) { 23 suite.Run(t, new(eventsTestSuite)) 24 } 25 26 func (s *eventsTestSuite) TestAppendEvents() { 27 e1 := sdk.NewEvent("transfer", sdk.NewAttribute("sender", "foo")) 28 e2 := sdk.NewEvent("transfer", sdk.NewAttribute("sender", "bar")) 29 a := sdk.Events{e1} 30 b := sdk.Events{e2} 31 c := a.AppendEvents(b) 32 s.Require().Equal(c, sdk.Events{e1, e2}) 33 s.Require().Equal(c, sdk.Events{e1}.AppendEvent(sdk.NewEvent("transfer", sdk.NewAttribute("sender", "bar")))) 34 s.Require().Equal(c, sdk.Events{e1}.AppendEvents(sdk.Events{e2})) 35 } 36 37 func (s *eventsTestSuite) TestAppendAttributes() { 38 e := sdk.NewEvent("transfer", sdk.NewAttribute("sender", "foo")) 39 e = e.AppendAttributes(sdk.NewAttribute("recipient", "bar")) 40 s.Require().Len(e.Attributes, 2) 41 s.Require().Equal(e, sdk.NewEvent("transfer", sdk.NewAttribute("sender", "foo"), sdk.NewAttribute("recipient", "bar"))) 42 } 43 44 func (s *eventsTestSuite) TestGetAttributes() { 45 e := sdk.NewEvent("transfer", sdk.NewAttribute("sender", "foo")) 46 e = e.AppendAttributes(sdk.NewAttribute("recipient", "bar")) 47 attr, found := e.GetAttribute("recipient") 48 s.Require().True(found) 49 s.Require().Equal(attr, sdk.NewAttribute("recipient", "bar")) 50 _, found = e.GetAttribute("foo") 51 s.Require().False(found) 52 53 events := sdk.Events{e}.AppendEvent(sdk.NewEvent("message", sdk.NewAttribute("sender", "bar"))) 54 attrs, found := events.GetAttributes("sender") 55 s.Require().True(found) 56 s.Require().Len(attrs, 2) 57 s.Require().Equal(attrs[0], sdk.NewAttribute("sender", "foo")) 58 s.Require().Equal(attrs[1], sdk.NewAttribute("sender", "bar")) 59 _, found = events.GetAttributes("foo") 60 s.Require().False(found) 61 } 62 63 func (s *eventsTestSuite) TestEmptyEvents() { 64 s.Require().Equal(sdk.EmptyEvents(), sdk.Events{}) 65 } 66 67 func (s *eventsTestSuite) TestAttributeString() { 68 s.Require().Equal("foo: bar", sdk.NewAttribute("foo", "bar").String()) 69 } 70 71 func (s *eventsTestSuite) TestToABCIEvents() { 72 e := sdk.Events{sdk.NewEvent("transfer", sdk.NewAttribute("sender", "foo"))} 73 abciEvents := e.ToABCIEvents() 74 s.Require().Len(abciEvents, 1) 75 s.Require().Equal(abciEvents[0].Type, e[0].Type) 76 s.Require().Equal(abciEvents[0].Attributes, e[0].Attributes) 77 } 78 79 func (s *eventsTestSuite) TestEventManager() { 80 em := sdk.NewEventManager() 81 event := sdk.NewEvent("reward", sdk.NewAttribute("x", "y")) 82 events := sdk.Events{sdk.NewEvent("transfer", sdk.NewAttribute("sender", "foo"))} 83 84 em.EmitEvents(events) 85 em.EmitEvent(event) 86 87 s.Require().Len(em.Events(), 2) 88 s.Require().Equal(em.Events(), events.AppendEvent(event)) 89 } 90 91 func (s *eventsTestSuite) TestEmitTypedEvent() { 92 s.Run("deterministic key-value order", func() { 93 for i := 0; i < 10; i++ { 94 em := sdk.NewEventManager() 95 coin := sdk.NewCoin("fakedenom", math.NewInt(1999999)) 96 s.Require().NoError(em.EmitTypedEvent(&coin)) 97 s.Require().Len(em.Events(), 1) 98 attrs := em.Events()[0].Attributes 99 s.Require().Len(attrs, 2) 100 s.Require().Equal(attrs[0].Key, "amount") 101 s.Require().Equal(attrs[1].Key, "denom") 102 } 103 }) 104 } 105 106 func (s *eventsTestSuite) TestEventManagerTypedEvents() { 107 em := sdk.NewEventManager() 108 109 coin := sdk.NewCoin("fakedenom", math.NewInt(1999999)) 110 cat := testdata.Cat{ 111 Moniker: "Garfield", 112 Lives: 6, 113 } 114 animal, err := codectypes.NewAnyWithValue(&cat) 115 s.Require().NoError(err) 116 hasAnimal := testdata.HasAnimal{ 117 X: 1000, 118 Animal: animal, 119 } 120 121 s.Require().NoError(em.EmitTypedEvents(&coin)) 122 s.Require().NoError(em.EmitTypedEvent(&hasAnimal)) 123 s.Require().Len(em.Events(), 2) 124 125 msg1, err := sdk.ParseTypedEvent(em.Events().ToABCIEvents()[0]) 126 s.Require().NoError(err) 127 s.Require().Equal(coin.String(), msg1.String()) 128 s.Require().Equal(reflect.TypeOf(&coin), reflect.TypeOf(msg1)) 129 130 msg2, err := sdk.ParseTypedEvent(em.Events().ToABCIEvents()[1]) 131 s.Require().NoError(err) 132 s.Require().Equal(reflect.TypeOf(&hasAnimal), reflect.TypeOf(msg2)) 133 response := msg2.(*testdata.HasAnimal) 134 s.Require().Equal(hasAnimal.Animal.String(), response.Animal.String()) 135 } 136 137 func (s *eventsTestSuite) TestStringifyEvents() { 138 cases := []struct { 139 name string 140 events sdk.Events 141 expTxtStr string 142 expJSONStr string 143 }{ 144 { 145 name: "default", 146 events: sdk.Events{ 147 sdk.NewEvent("message", sdk.NewAttribute(sdk.AttributeKeySender, "foo")), 148 sdk.NewEvent("message", sdk.NewAttribute(sdk.AttributeKeyModule, "bank")), 149 }, 150 expTxtStr: "\t\t- message\n\t\t\t- sender: foo\n\t\t- message\n\t\t\t- module: bank", 151 expJSONStr: "[{\"type\":\"message\",\"attributes\":[{\"key\":\"sender\",\"value\":\"foo\"}]},{\"type\":\"message\",\"attributes\":[{\"key\":\"module\",\"value\":\"bank\"}]}]", 152 }, 153 { 154 name: "multiple events with same attributes", 155 events: sdk.Events{ 156 sdk.NewEvent( 157 "message", 158 sdk.NewAttribute(sdk.AttributeKeyModule, "staking"), 159 sdk.NewAttribute(sdk.AttributeKeySender, "cosmos1foo"), 160 ), 161 sdk.NewEvent("message", sdk.NewAttribute(sdk.AttributeKeySender, "foo")), 162 }, 163 expTxtStr: "\t\t- message\n\t\t\t- module: staking\n\t\t\t- sender: cosmos1foo\n\t\t- message\n\t\t\t- sender: foo", 164 expJSONStr: `[{"type":"message","attributes":[{"key":"module","value":"staking"},{"key":"sender","value":"cosmos1foo"}]},{"type":"message","attributes":[{"key":"sender","value":"foo"}]}]`, 165 }, 166 } 167 168 for _, test := range cases { 169 se := sdk.StringifyEvents(test.events.ToABCIEvents()) 170 s.Require().Equal(test.expTxtStr, se.String()) 171 bz, err := json.Marshal(se) 172 s.Require().NoError(err) 173 s.Require().Equal(test.expJSONStr, string(bz)) 174 } 175 } 176 177 func (s *eventsTestSuite) TestMarkEventsToIndex() { 178 events := []abci.Event{ 179 { 180 Type: "message", 181 Attributes: []abci.EventAttribute{ 182 {Key: "sender", Value: "foo"}, 183 {Key: "recipient", Value: "bar"}, 184 }, 185 }, 186 { 187 Type: "staking", 188 Attributes: []abci.EventAttribute{ 189 {Key: "deposit", Value: "5"}, 190 {Key: "unbond", Value: "10"}, 191 }, 192 }, 193 } 194 195 testCases := map[string]struct { 196 events []abci.Event 197 indexSet map[string]struct{} 198 expected []abci.Event 199 }{ 200 "empty index set": { 201 events: events, 202 expected: []abci.Event{ 203 { 204 Type: "message", 205 Attributes: []abci.EventAttribute{ 206 {Key: "sender", Value: "foo", Index: true}, 207 {Key: "recipient", Value: "bar", Index: true}, 208 }, 209 }, 210 { 211 Type: "staking", 212 Attributes: []abci.EventAttribute{ 213 {Key: "deposit", Value: "5", Index: true}, 214 {Key: "unbond", Value: "10", Index: true}, 215 }, 216 }, 217 }, 218 indexSet: map[string]struct{}{}, 219 }, 220 "index some events": { 221 events: events, 222 expected: []abci.Event{ 223 { 224 Type: "message", 225 Attributes: []abci.EventAttribute{ 226 {Key: "sender", Value: "foo", Index: true}, 227 {Key: "recipient", Value: "bar"}, 228 }, 229 }, 230 { 231 Type: "staking", 232 Attributes: []abci.EventAttribute{ 233 {Key: "deposit", Value: "5", Index: true}, 234 {Key: "unbond", Value: "10"}, 235 }, 236 }, 237 }, 238 indexSet: map[string]struct{}{ 239 "message.sender": {}, 240 "staking.deposit": {}, 241 }, 242 }, 243 "index all events": { 244 events: events, 245 expected: []abci.Event{ 246 { 247 Type: "message", 248 Attributes: []abci.EventAttribute{ 249 {Key: "sender", Value: "foo", Index: true}, 250 {Key: "recipient", Value: "bar", Index: true}, 251 }, 252 }, 253 { 254 Type: "staking", 255 Attributes: []abci.EventAttribute{ 256 {Key: "deposit", Value: "5", Index: true}, 257 {Key: "unbond", Value: "10", Index: true}, 258 }, 259 }, 260 }, 261 indexSet: map[string]struct{}{ 262 "message.sender": {}, 263 "message.recipient": {}, 264 "staking.deposit": {}, 265 "staking.unbond": {}, 266 }, 267 }, 268 } 269 270 for name, tc := range testCases { 271 tc := tc 272 s.T().Run(name, func(_ *testing.T) { 273 s.Require().Equal(tc.expected, sdk.MarkEventsToIndex(tc.events, tc.indexSet)) 274 }) 275 } 276 }