eventsourcing 9.3.3__py3-none-any.whl → 9.3.4__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of eventsourcing might be problematic. Click here for more details.

Files changed (127) hide show
  1. {eventsourcing-9.3.3.dist-info → eventsourcing-9.3.4.dist-info}/METADATA +1 -1
  2. eventsourcing-9.3.4.dist-info/RECORD +24 -0
  3. eventsourcing/examples/__init__.py +0 -0
  4. eventsourcing/examples/aggregate1/__init__.py +0 -0
  5. eventsourcing/examples/aggregate1/application.py +0 -27
  6. eventsourcing/examples/aggregate1/domainmodel.py +0 -16
  7. eventsourcing/examples/aggregate1/test_application.py +0 -37
  8. eventsourcing/examples/aggregate2/__init__.py +0 -0
  9. eventsourcing/examples/aggregate2/application.py +0 -27
  10. eventsourcing/examples/aggregate2/domainmodel.py +0 -22
  11. eventsourcing/examples/aggregate2/test_application.py +0 -37
  12. eventsourcing/examples/aggregate3/__init__.py +0 -0
  13. eventsourcing/examples/aggregate3/application.py +0 -27
  14. eventsourcing/examples/aggregate3/domainmodel.py +0 -38
  15. eventsourcing/examples/aggregate3/test_application.py +0 -37
  16. eventsourcing/examples/aggregate4/__init__.py +0 -0
  17. eventsourcing/examples/aggregate4/application.py +0 -27
  18. eventsourcing/examples/aggregate4/domainmodel.py +0 -114
  19. eventsourcing/examples/aggregate4/test_application.py +0 -38
  20. eventsourcing/examples/aggregate5/__init__.py +0 -0
  21. eventsourcing/examples/aggregate5/application.py +0 -27
  22. eventsourcing/examples/aggregate5/domainmodel.py +0 -131
  23. eventsourcing/examples/aggregate5/test_application.py +0 -38
  24. eventsourcing/examples/aggregate6/__init__.py +0 -0
  25. eventsourcing/examples/aggregate6/application.py +0 -30
  26. eventsourcing/examples/aggregate6/domainmodel.py +0 -123
  27. eventsourcing/examples/aggregate6/test_application.py +0 -38
  28. eventsourcing/examples/aggregate6a/__init__.py +0 -0
  29. eventsourcing/examples/aggregate6a/application.py +0 -40
  30. eventsourcing/examples/aggregate6a/domainmodel.py +0 -149
  31. eventsourcing/examples/aggregate6a/test_application.py +0 -45
  32. eventsourcing/examples/aggregate7/__init__.py +0 -0
  33. eventsourcing/examples/aggregate7/application.py +0 -53
  34. eventsourcing/examples/aggregate7/domainmodel.py +0 -142
  35. eventsourcing/examples/aggregate7/persistence.py +0 -57
  36. eventsourcing/examples/aggregate7/test_application.py +0 -45
  37. eventsourcing/examples/aggregate7/test_compression_and_encryption.py +0 -45
  38. eventsourcing/examples/aggregate7/test_snapshotting_intervals.py +0 -67
  39. eventsourcing/examples/aggregate7a/__init__.py +0 -0
  40. eventsourcing/examples/aggregate7a/application.py +0 -56
  41. eventsourcing/examples/aggregate7a/domainmodel.py +0 -168
  42. eventsourcing/examples/aggregate7a/test_application.py +0 -46
  43. eventsourcing/examples/aggregate7a/test_compression_and_encryption.py +0 -45
  44. eventsourcing/examples/aggregate8/__init__.py +0 -0
  45. eventsourcing/examples/aggregate8/application.py +0 -47
  46. eventsourcing/examples/aggregate8/domainmodel.py +0 -71
  47. eventsourcing/examples/aggregate8/persistence.py +0 -57
  48. eventsourcing/examples/aggregate8/test_application.py +0 -44
  49. eventsourcing/examples/aggregate8/test_compression_and_encryption.py +0 -44
  50. eventsourcing/examples/aggregate8/test_snapshotting_intervals.py +0 -38
  51. eventsourcing/examples/bankaccounts/__init__.py +0 -0
  52. eventsourcing/examples/bankaccounts/application.py +0 -70
  53. eventsourcing/examples/bankaccounts/domainmodel.py +0 -56
  54. eventsourcing/examples/bankaccounts/test.py +0 -173
  55. eventsourcing/examples/cargoshipping/__init__.py +0 -0
  56. eventsourcing/examples/cargoshipping/application.py +0 -126
  57. eventsourcing/examples/cargoshipping/domainmodel.py +0 -330
  58. eventsourcing/examples/cargoshipping/interface.py +0 -143
  59. eventsourcing/examples/cargoshipping/test.py +0 -231
  60. eventsourcing/examples/contentmanagement/__init__.py +0 -0
  61. eventsourcing/examples/contentmanagement/application.py +0 -118
  62. eventsourcing/examples/contentmanagement/domainmodel.py +0 -69
  63. eventsourcing/examples/contentmanagement/test.py +0 -180
  64. eventsourcing/examples/contentmanagement/utils.py +0 -26
  65. eventsourcing/examples/contentmanagementsystem/__init__.py +0 -0
  66. eventsourcing/examples/contentmanagementsystem/application.py +0 -54
  67. eventsourcing/examples/contentmanagementsystem/postgres.py +0 -17
  68. eventsourcing/examples/contentmanagementsystem/sqlite.py +0 -17
  69. eventsourcing/examples/contentmanagementsystem/system.py +0 -14
  70. eventsourcing/examples/contentmanagementsystem/test_system.py +0 -180
  71. eventsourcing/examples/searchablecontent/__init__.py +0 -0
  72. eventsourcing/examples/searchablecontent/application.py +0 -45
  73. eventsourcing/examples/searchablecontent/persistence.py +0 -23
  74. eventsourcing/examples/searchablecontent/postgres.py +0 -118
  75. eventsourcing/examples/searchablecontent/sqlite.py +0 -136
  76. eventsourcing/examples/searchablecontent/test_application.py +0 -110
  77. eventsourcing/examples/searchablecontent/test_recorder.py +0 -68
  78. eventsourcing/examples/searchabletimestamps/__init__.py +0 -0
  79. eventsourcing/examples/searchabletimestamps/application.py +0 -32
  80. eventsourcing/examples/searchabletimestamps/persistence.py +0 -20
  81. eventsourcing/examples/searchabletimestamps/postgres.py +0 -110
  82. eventsourcing/examples/searchabletimestamps/sqlite.py +0 -99
  83. eventsourcing/examples/searchabletimestamps/test_searchabletimestamps.py +0 -94
  84. eventsourcing/examples/test_invoice.py +0 -176
  85. eventsourcing/examples/test_parking_lot.py +0 -206
  86. eventsourcing/tests/application_tests/__init__.py +0 -0
  87. eventsourcing/tests/application_tests/test_application_with_automatic_snapshotting.py +0 -55
  88. eventsourcing/tests/application_tests/test_application_with_popo.py +0 -22
  89. eventsourcing/tests/application_tests/test_application_with_postgres.py +0 -75
  90. eventsourcing/tests/application_tests/test_application_with_sqlite.py +0 -72
  91. eventsourcing/tests/application_tests/test_cache.py +0 -134
  92. eventsourcing/tests/application_tests/test_event_sourced_log.py +0 -162
  93. eventsourcing/tests/application_tests/test_notificationlog.py +0 -232
  94. eventsourcing/tests/application_tests/test_notificationlogreader.py +0 -126
  95. eventsourcing/tests/application_tests/test_processapplication.py +0 -110
  96. eventsourcing/tests/application_tests/test_processingpolicy.py +0 -109
  97. eventsourcing/tests/application_tests/test_repository.py +0 -504
  98. eventsourcing/tests/application_tests/test_snapshotting.py +0 -68
  99. eventsourcing/tests/application_tests/test_upcasting.py +0 -459
  100. eventsourcing/tests/docs_tests/__init__.py +0 -0
  101. eventsourcing/tests/docs_tests/test_docs.py +0 -293
  102. eventsourcing/tests/domain_tests/__init__.py +0 -0
  103. eventsourcing/tests/domain_tests/test_aggregate.py +0 -1200
  104. eventsourcing/tests/domain_tests/test_aggregate_decorators.py +0 -1604
  105. eventsourcing/tests/domain_tests/test_domainevent.py +0 -80
  106. eventsourcing/tests/interface_tests/__init__.py +0 -0
  107. eventsourcing/tests/interface_tests/test_remotenotificationlog.py +0 -258
  108. eventsourcing/tests/persistence_tests/__init__.py +0 -0
  109. eventsourcing/tests/persistence_tests/test_aes.py +0 -93
  110. eventsourcing/tests/persistence_tests/test_connection_pool.py +0 -722
  111. eventsourcing/tests/persistence_tests/test_eventstore.py +0 -72
  112. eventsourcing/tests/persistence_tests/test_infrastructure_factory.py +0 -21
  113. eventsourcing/tests/persistence_tests/test_mapper.py +0 -113
  114. eventsourcing/tests/persistence_tests/test_noninterleaving_notification_ids.py +0 -69
  115. eventsourcing/tests/persistence_tests/test_popo.py +0 -124
  116. eventsourcing/tests/persistence_tests/test_postgres.py +0 -1120
  117. eventsourcing/tests/persistence_tests/test_sqlite.py +0 -348
  118. eventsourcing/tests/persistence_tests/test_transcoder.py +0 -44
  119. eventsourcing/tests/system_tests/__init__.py +0 -0
  120. eventsourcing/tests/system_tests/test_runner.py +0 -935
  121. eventsourcing/tests/system_tests/test_system.py +0 -284
  122. eventsourcing/tests/utils_tests/__init__.py +0 -0
  123. eventsourcing/tests/utils_tests/test_utils.py +0 -226
  124. eventsourcing-9.3.3.dist-info/RECORD +0 -145
  125. {eventsourcing-9.3.3.dist-info → eventsourcing-9.3.4.dist-info}/AUTHORS +0 -0
  126. {eventsourcing-9.3.3.dist-info → eventsourcing-9.3.4.dist-info}/LICENSE +0 -0
  127. {eventsourcing-9.3.3.dist-info → eventsourcing-9.3.4.dist-info}/WHEEL +0 -0
@@ -1,126 +0,0 @@
1
- from itertools import chain
2
- from unittest.case import TestCase
3
- from uuid import uuid4
4
-
5
- from eventsourcing.application import LocalNotificationLog
6
- from eventsourcing.persistence import StoredEvent
7
- from eventsourcing.sqlite import SQLiteDatastore, SQLiteProcessRecorder
8
- from eventsourcing.system import NotificationLogReader
9
-
10
-
11
- class TestNotificationLogReader(TestCase):
12
- def test_read(self):
13
- recorder = SQLiteProcessRecorder(SQLiteDatastore(":memory:"))
14
- recorder.create_table()
15
-
16
- # Construct notification log.
17
- notification_log = LocalNotificationLog(recorder, section_size=5)
18
- reader = NotificationLogReader(notification_log, section_size=10)
19
- notifications = list(reader.read(start=1))
20
- self.assertEqual(len(notifications), 0)
21
-
22
- # Write 5 events.
23
- originator_id = uuid4()
24
- for i in range(5):
25
- stored_event = StoredEvent(
26
- originator_id=originator_id,
27
- originator_version=i,
28
- topic="topic",
29
- state=b"state",
30
- )
31
- recorder.insert_events(
32
- [stored_event],
33
- )
34
-
35
- notifications = list(reader.read(start=1))
36
- self.assertEqual(len(notifications), 5)
37
-
38
- # Write 4 events.
39
- originator_id = uuid4()
40
- for i in range(4):
41
- stored_event = StoredEvent(
42
- originator_id=originator_id,
43
- originator_version=i,
44
- topic="topic",
45
- state=b"state",
46
- )
47
- recorder.insert_events([stored_event])
48
-
49
- notifications = list(reader.read(start=1))
50
- self.assertEqual(len(notifications), 9)
51
-
52
- notifications = list(reader.read(start=2))
53
- self.assertEqual(len(notifications), 8)
54
-
55
- notifications = list(reader.read(start=3))
56
- self.assertEqual(len(notifications), 7)
57
-
58
- notifications = list(reader.read(start=4))
59
- self.assertEqual(len(notifications), 6)
60
-
61
- notifications = list(reader.read(start=8))
62
- self.assertEqual(len(notifications), 2)
63
-
64
- notifications = list(reader.read(start=9))
65
- self.assertEqual(len(notifications), 1)
66
-
67
- notifications = list(reader.read(start=10))
68
- self.assertEqual(len(notifications), 0)
69
-
70
- def test_select(self):
71
- recorder = SQLiteProcessRecorder(SQLiteDatastore(":memory:"))
72
- recorder.create_table()
73
-
74
- # Construct notification log.
75
- notification_log = LocalNotificationLog(recorder, section_size=5)
76
- reader = NotificationLogReader(notification_log, section_size=5)
77
- notifications = list(chain(*reader.select(start=1)))
78
- self.assertEqual(len(notifications), 0)
79
-
80
- # Write 5 events.
81
- originator_id = uuid4()
82
- for i in range(5):
83
- stored_event = StoredEvent(
84
- originator_id=originator_id,
85
- originator_version=i,
86
- topic="topic",
87
- state=b"state",
88
- )
89
- recorder.insert_events(
90
- [stored_event],
91
- )
92
-
93
- notifications = list(chain(*reader.select(start=1)))
94
- self.assertEqual(len(notifications), 5)
95
-
96
- # Write 4 events.
97
- originator_id = uuid4()
98
- for i in range(4):
99
- stored_event = StoredEvent(
100
- originator_id=originator_id,
101
- originator_version=i,
102
- topic="topic",
103
- state=b"state",
104
- )
105
- recorder.insert_events([stored_event])
106
-
107
- notifications = list(chain(*reader.select(start=1)))
108
- self.assertEqual(len(notifications), 9)
109
-
110
- notifications = list(chain(*reader.select(start=2)))
111
- self.assertEqual(len(notifications), 8)
112
-
113
- notifications = list(chain(*reader.select(start=3)))
114
- self.assertEqual(len(notifications), 7)
115
-
116
- notifications = list(chain(*reader.select(start=4)))
117
- self.assertEqual(len(notifications), 6)
118
-
119
- notifications = list(chain(*reader.select(start=8)))
120
- self.assertEqual(len(notifications), 2)
121
-
122
- notifications = list(chain(*reader.select(start=9)))
123
- self.assertEqual(len(notifications), 1)
124
-
125
- notifications = list(chain(*reader.select(start=10)))
126
- self.assertEqual(len(notifications), 0)
@@ -1,110 +0,0 @@
1
- from unittest.case import TestCase
2
-
3
- from eventsourcing.application import RecordingEvent
4
- from eventsourcing.dispatch import singledispatchmethod
5
- from eventsourcing.domain import AggregateEvent
6
- from eventsourcing.persistence import Transcoder
7
- from eventsourcing.system import (
8
- Follower,
9
- Leader,
10
- ProcessApplication,
11
- ProcessingEvent,
12
- RecordingEventReceiver,
13
- )
14
- from eventsourcing.tests.application import BankAccounts, EmailAddressAsStr
15
- from eventsourcing.tests.application_tests.test_processingpolicy import (
16
- EmailNotification,
17
- )
18
- from eventsourcing.tests.domain import BankAccount
19
-
20
-
21
- class TestProcessApplication(TestCase):
22
- def test_pull_and_process(self):
23
- leader_cls = type(
24
- BankAccounts.__name__,
25
- (BankAccounts, Leader),
26
- {},
27
- )
28
-
29
- accounts = leader_cls()
30
- email_process = EmailProcess()
31
- email_process.follow(
32
- accounts.name,
33
- accounts.notification_log,
34
- )
35
-
36
- section = email_process.notification_log["1,5"]
37
- self.assertEqual(len(section.items), 0)
38
-
39
- accounts.open_account("Alice", "alice@example.com")
40
-
41
- email_process.pull_and_process(BankAccounts.name)
42
-
43
- section = email_process.notification_log["1,5"]
44
- self.assertEqual(len(section.items), 1)
45
-
46
- # Check we have processed the first event.
47
- self.assertEqual(email_process.recorder.max_tracking_id(BankAccounts.name), 1)
48
-
49
- # Check reprocessing first event changes nothing (swallows IntegrityError).
50
- email_process.pull_and_process(BankAccounts.name, start=1)
51
- self.assertEqual(email_process.recorder.max_tracking_id(BankAccounts.name), 1)
52
-
53
- # Check we can continue from the next position.
54
- email_process.pull_and_process(BankAccounts.name, start=2)
55
-
56
- # Check we haven't actually processed anything further.
57
- self.assertEqual(email_process.recorder.max_tracking_id(BankAccounts.name), 1)
58
- section = email_process.notification_log["1,5"]
59
- self.assertEqual(len(section.items), 1)
60
-
61
- # Subscribe for notifications.
62
- accounts.lead(PromptForwarder(email_process))
63
-
64
- # Create another notification.
65
- accounts.open_account("Bob", "bob@example.com")
66
-
67
- # Check we have processed the next notification.
68
- section = email_process.notification_log["1,5"]
69
- self.assertEqual(len(section.items), 2)
70
-
71
- # Check we have actually processed the second event.
72
- self.assertEqual(email_process.recorder.max_tracking_id(BankAccounts.name), 2)
73
-
74
-
75
- class EmailProcess(ProcessApplication):
76
- def register_transcodings(self, transcoder: Transcoder) -> None:
77
- super().register_transcodings(transcoder)
78
- transcoder.register(EmailAddressAsStr())
79
-
80
- @singledispatchmethod
81
- def policy(
82
- self,
83
- domain_event: AggregateEvent,
84
- processing_event: ProcessingEvent,
85
- ):
86
- """Default policy"""
87
-
88
- @policy.register
89
- def _(
90
- self,
91
- domain_event: BankAccount.Opened,
92
- processing_event: ProcessingEvent,
93
- ):
94
- notification = EmailNotification.create(
95
- to=domain_event.email_address,
96
- subject="Your New Account",
97
- message=f"Dear {domain_event.full_name}, ...",
98
- )
99
- processing_event.collect_events(notification)
100
-
101
-
102
- class PromptForwarder(RecordingEventReceiver):
103
- def __init__(self, application: Follower):
104
- self.application = application
105
-
106
- def receive_recording_event(self, recording_event: RecordingEvent) -> None:
107
- self.application.pull_and_process(
108
- leader_name=recording_event.application_name,
109
- start=recording_event.recordings[0].notification.id,
110
- )
@@ -1,109 +0,0 @@
1
- import warnings
2
- from unittest.case import TestCase
3
- from uuid import uuid4
4
-
5
- from eventsourcing.domain import Aggregate
6
- from eventsourcing.persistence import Tracking
7
- from eventsourcing.system import ProcessingEvent
8
- from eventsourcing.tests.domain import BankAccount
9
-
10
-
11
- def policy(domain_event, processing_event: ProcessingEvent):
12
- if isinstance(domain_event, BankAccount.Opened):
13
- notification = EmailNotification.create(
14
- to=domain_event.email_address,
15
- subject="Your New Account",
16
- message=f"Dear {domain_event.full_name}",
17
- )
18
- processing_event.collect_events(notification)
19
-
20
-
21
- def policy_legacy_save(domain_event, processing_event: ProcessingEvent):
22
- if isinstance(domain_event, BankAccount.Opened):
23
- notification = EmailNotification.create(
24
- to=domain_event.email_address,
25
- subject="Your New Account",
26
- message=f"Dear {domain_event.full_name}",
27
- )
28
- processing_event.save(notification)
29
-
30
-
31
- class TestProcessingPolicy(TestCase):
32
- def test_policy(self):
33
- # Open an account.
34
- account = BankAccount.open(
35
- full_name="Alice",
36
- email_address="alice@example.com",
37
- )
38
- events = account.collect_events()
39
- created_event = events[0]
40
-
41
- processing_event = ProcessingEvent(
42
- tracking=Tracking(
43
- application_name="upstream_app",
44
- notification_id=5,
45
- )
46
- )
47
-
48
- policy(created_event, processing_event)
49
-
50
- self.assertEqual(len(processing_event.events), 1)
51
- self.assertIsInstance(
52
- processing_event.events[0],
53
- EmailNotification.Created,
54
- )
55
-
56
- def test_legacy_save(self):
57
- # Open an account.
58
- account = BankAccount.open(
59
- full_name="Alice",
60
- email_address="alice@example.com",
61
- )
62
- events = account.collect_events()
63
- created_event = events[0]
64
-
65
- processing_event = ProcessingEvent(
66
- tracking=Tracking(
67
- application_name="upstream_app",
68
- notification_id=5,
69
- )
70
- )
71
-
72
- # Verify deprecation warning.
73
- with warnings.catch_warnings(record=True) as w:
74
- policy_legacy_save(created_event, processing_event)
75
-
76
- self.assertEqual(1, len(w))
77
- self.assertIs(w[-1].category, DeprecationWarning)
78
- self.assertEqual(
79
- "'save()' is deprecated, use 'collect_events()' instead",
80
- w[-1].message.args[0],
81
- )
82
-
83
- self.assertEqual(len(processing_event.events), 1)
84
- self.assertIsInstance(
85
- processing_event.events[0],
86
- EmailNotification.Created,
87
- )
88
-
89
-
90
- class EmailNotification(Aggregate):
91
- def __init__(self, to, subject, message):
92
- self.to = to
93
- self.subject = subject
94
- self.message = message
95
-
96
- @classmethod
97
- def create(cls, to, subject, message):
98
- return cls._create(
99
- cls.Created,
100
- id=uuid4(),
101
- to=to,
102
- subject=subject,
103
- message=message,
104
- )
105
-
106
- class Created(Aggregate.Created):
107
- to: str
108
- subject: str
109
- message: str