Skip to content

Commit 8483e8e

Browse files
feat: event attribute get operation support (#165)
* feat: get operation support Signed-off-by: Alexander Tkachev <[email protected]> * docs: event get operation Signed-off-by: Alexander Tkachev <[email protected]> * test: extract dummy attributes into a fixture Signed-off-by: Alexander Tkachev <[email protected]> * test: extract common dummy data into consts Signed-off-by: Alexander Tkachev <[email protected]> * test: event get operation Signed-off-by: Alexander Tkachev <[email protected]> * docs: return value Signed-off-by: Alexander Tkachev <[email protected]> * test: remove assertion Signed-off-by: Alexander Tkachev <[email protected]> * test: move dummy data into fixtures Signed-off-by: Alexander Tkachev <[email protected]> * style: black formatting Signed-off-by: Alexander Tkachev <[email protected]> * style: black formatting Signed-off-by: Alexander Tkachev <[email protected]> * docs: fix bad grammar Signed-off-by: Alexander Tkachev <[email protected]> * test: style fix line too long Signed-off-by: Alexander Tkachev <[email protected]> * style: fix line too long Signed-off-by: Alexander Tkachev <[email protected]>
1 parent aee384b commit 8483e8e

File tree

2 files changed

+105
-31
lines changed

2 files changed

+105
-31
lines changed

cloudevents/http/event.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,22 @@ def __eq__(self, other):
7777
def __getitem__(self, key):
7878
return self._attributes[key]
7979

80+
def get(
81+
self, key: str, default: typing.Optional[typing.Any] = None
82+
) -> typing.Optional[typing.Any]:
83+
"""
84+
Retrieves an event attribute value for the given key.
85+
Returns the default value if not attribute for the given key exists.
86+
87+
MUST NOT throw an exception when the key does not exist.
88+
89+
:param key: The event attribute name.
90+
:param default: The default value to be returned when
91+
no attribute with the given key exists.
92+
:returns: The event attribute value if exists, default value otherwise.
93+
"""
94+
return self._attributes.get(key, default)
95+
8096
def __setitem__(self, key, value):
8197
self._attributes[key] = value
8298

cloudevents/tests/test_http_cloudevent.py

Lines changed: 89 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,14 @@
55
from cloudevents.http.util import _json_or_string
66

77

8-
@pytest.mark.parametrize("specversion", ["0.3", "1.0"])
9-
def test_http_cloudevent_equality(specversion):
10-
attributes = {
8+
@pytest.fixture(params=["0.3", "1.0"])
9+
def specversion(request):
10+
return request.param
11+
12+
13+
@pytest.fixture()
14+
def dummy_attributes(specversion):
15+
return {
1116
"source": "<source>",
1217
"specversion": specversion,
1318
"id": "my-id",
@@ -16,48 +21,55 @@ def test_http_cloudevent_equality(specversion):
1621
"datacontenttype": "application/json",
1722
"subject": "my-subject",
1823
}
19-
data = '{"name":"john"}'
20-
event1 = CloudEvent(attributes, data)
21-
event2 = CloudEvent(attributes, data)
24+
25+
26+
@pytest.fixture()
27+
def my_dummy_data():
28+
return '{"name":"john"}'
29+
30+
31+
@pytest.fixture()
32+
def your_dummy_data():
33+
return '{"name":"paul"}'
34+
35+
36+
def test_http_cloudevent_equality(
37+
dummy_attributes, my_dummy_data, your_dummy_data
38+
):
39+
data = my_dummy_data
40+
event1 = CloudEvent(dummy_attributes, data)
41+
event2 = CloudEvent(dummy_attributes, data)
2242
assert event1 == event2
2343
# Test different attributes
24-
for key in attributes:
44+
for key in dummy_attributes:
2545
if key == "specversion":
2646
continue
2747
else:
28-
attributes[key] = f"noise-{key}"
29-
event3 = CloudEvent(attributes, data)
30-
event2 = CloudEvent(attributes, data)
48+
dummy_attributes[key] = f"noise-{key}"
49+
event3 = CloudEvent(dummy_attributes, data)
50+
event2 = CloudEvent(dummy_attributes, data)
3151
assert event2 == event3
3252
assert event1 != event2 and event3 != event1
3353

3454
# Test different data
35-
data = '{"name":"paul"}'
36-
event3 = CloudEvent(attributes, data)
37-
event2 = CloudEvent(attributes, data)
55+
data = your_dummy_data
56+
event3 = CloudEvent(dummy_attributes, data)
57+
event2 = CloudEvent(dummy_attributes, data)
3858
assert event2 == event3
3959
assert event1 != event2 and event3 != event1
4060

4161

42-
@pytest.mark.parametrize("specversion", ["0.3", "1.0"])
43-
def test_http_cloudevent_mutates_equality(specversion):
44-
attributes = {
45-
"source": "<source>",
46-
"specversion": specversion,
47-
"id": "my-id",
48-
"time": "tomorrow",
49-
"type": "tests.cloudevents.override",
50-
"datacontenttype": "application/json",
51-
"subject": "my-subject",
52-
}
53-
data = '{"name":"john"}'
54-
event1 = CloudEvent(attributes, data)
55-
event2 = CloudEvent(attributes, data)
56-
event3 = CloudEvent(attributes, data)
62+
def test_http_cloudevent_mutates_equality(
63+
dummy_attributes, my_dummy_data, your_dummy_data
64+
):
65+
data = my_dummy_data
66+
event1 = CloudEvent(dummy_attributes, data)
67+
event2 = CloudEvent(dummy_attributes, data)
68+
event3 = CloudEvent(dummy_attributes, data)
5769

5870
assert event1 == event2
5971
# Test different attributes
60-
for key in attributes:
72+
for key in dummy_attributes:
6173
if key == "specversion":
6274
continue
6375
else:
@@ -67,8 +79,8 @@ def test_http_cloudevent_mutates_equality(specversion):
6779
assert event1 != event2 and event3 != event1
6880

6981
# Test different data
70-
event2.data = '{"name":"paul"}'
71-
event3.data = '{"name":"paul"}'
82+
event2.data = your_dummy_data
83+
event3.data = your_dummy_data
7284
assert event2 == event3
7385
assert event1 != event2 and event3 != event1
7486

@@ -119,3 +131,49 @@ def test_cloudevent_general_overrides():
119131

120132
def test_none_json_or_string():
121133
assert _json_or_string(None) is None
134+
135+
136+
@pytest.fixture()
137+
def dummy_event(dummy_attributes, my_dummy_data):
138+
return CloudEvent(attributes=dummy_attributes, data=my_dummy_data)
139+
140+
141+
@pytest.fixture()
142+
def non_exiting_attribute_name(dummy_event):
143+
result = "nonexisting"
144+
assert result not in dummy_event
145+
return result
146+
147+
148+
def test_get_operation_on_non_existing_attribute_must_not_raise_exception(
149+
dummy_event, non_exiting_attribute_name
150+
):
151+
dummy_event.get(non_exiting_attribute_name)
152+
153+
154+
def test_get_must_return_attribute_value_if_exists(dummy_event):
155+
assert dummy_event.get("source") == dummy_event["source"]
156+
157+
158+
def test_get_operation_on_non_existing_attribute_must_return_none_by_default(
159+
dummy_event, non_exiting_attribute_name
160+
):
161+
assert dummy_event.get(non_exiting_attribute_name) is None
162+
163+
164+
def test_get_operation_on_non_existing_attribute_must_return_default_value_if_given(
165+
dummy_event, non_exiting_attribute_name
166+
):
167+
dummy_value = "Hello World"
168+
assert (
169+
dummy_event.get(non_exiting_attribute_name, dummy_value) == dummy_value
170+
)
171+
172+
173+
def test_get_operation_on_non_existing_attribute_should_not_copy_default_value(
174+
dummy_event, non_exiting_attribute_name
175+
):
176+
dummy_value = object()
177+
assert (
178+
dummy_event.get(non_exiting_attribute_name, dummy_value) is dummy_value
179+
)

0 commit comments

Comments
 (0)