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,75 +0,0 @@
1
- import os
2
- from unittest import TestCase
3
-
4
- from eventsourcing.postgres import PostgresDatastore
5
- from eventsourcing.tests.application import (
6
- TIMEIT_FACTOR,
7
- ApplicationTestCase,
8
- ExampleApplicationTestCase,
9
- )
10
- from eventsourcing.tests.postgres_utils import drop_postgres_table
11
-
12
-
13
- class WithPostgres(TestCase):
14
- timeit_number = 5 * TIMEIT_FACTOR
15
- expected_factory_topic = "eventsourcing.postgres:Factory"
16
-
17
- def setUp(self) -> None:
18
- super().setUp()
19
-
20
- os.environ["PERSISTENCE_MODULE"] = "eventsourcing.postgres"
21
- os.environ["CREATE_TABLE"] = "y"
22
- os.environ["POSTGRES_DBNAME"] = "eventsourcing"
23
- os.environ["POSTGRES_HOST"] = "127.0.0.1"
24
- os.environ["POSTGRES_PORT"] = "5432"
25
- os.environ["POSTGRES_USER"] = "eventsourcing"
26
- os.environ["POSTGRES_PASSWORD"] = "eventsourcing" # noqa: S105
27
- os.environ["POSTGRES_SCHEMA"] = "public"
28
-
29
- db = PostgresDatastore(
30
- os.getenv("POSTGRES_DBNAME"),
31
- os.getenv("POSTGRES_HOST"),
32
- os.getenv("POSTGRES_PORT"),
33
- os.getenv("POSTGRES_USER"),
34
- os.getenv("POSTGRES_PASSWORD"),
35
- )
36
- drop_postgres_table(db, "public.bankaccounts_events")
37
- drop_postgres_table(db, "public.bankaccounts_snapshots")
38
- db.close()
39
-
40
- def tearDown(self) -> None:
41
- db = PostgresDatastore(
42
- os.getenv("POSTGRES_DBNAME"),
43
- os.getenv("POSTGRES_HOST"),
44
- os.getenv("POSTGRES_PORT"),
45
- os.getenv("POSTGRES_USER"),
46
- os.getenv("POSTGRES_PASSWORD"),
47
- )
48
- drop_postgres_table(db, "public.bankaccounts_events")
49
- drop_postgres_table(db, "public.bankaccounts_snapshots")
50
-
51
- del os.environ["PERSISTENCE_MODULE"]
52
- del os.environ["CREATE_TABLE"]
53
- del os.environ["POSTGRES_DBNAME"]
54
- del os.environ["POSTGRES_HOST"]
55
- del os.environ["POSTGRES_PORT"]
56
- del os.environ["POSTGRES_USER"]
57
- del os.environ["POSTGRES_PASSWORD"]
58
- del os.environ["POSTGRES_SCHEMA"]
59
- db.close()
60
-
61
- super().tearDown()
62
-
63
-
64
- class TestApplicationWithPostgres(ApplicationTestCase, WithPostgres):
65
- pass
66
-
67
-
68
- class TestExampleApplicationWithPostgres(ExampleApplicationTestCase, WithPostgres):
69
- timeit_number = 5 * TIMEIT_FACTOR
70
- expected_factory_topic = "eventsourcing.postgres:Factory"
71
-
72
-
73
- del ApplicationTestCase
74
- del ExampleApplicationTestCase
75
- del WithPostgres
@@ -1,72 +0,0 @@
1
- import os
2
- from unittest import TestCase
3
-
4
- from eventsourcing.tests.application import (
5
- TIMEIT_FACTOR,
6
- ApplicationTestCase,
7
- ExampleApplicationTestCase,
8
- )
9
- from eventsourcing.tests.persistence import tmpfile_uris
10
-
11
-
12
- class WithSQLiteFile(TestCase):
13
- timeit_number = 30 * TIMEIT_FACTOR
14
- expected_factory_topic = "eventsourcing.sqlite:Factory"
15
-
16
- def setUp(self) -> None:
17
- super().setUp()
18
- self.uris = tmpfile_uris()
19
- # self.db_uri = next(self.uris)
20
-
21
- os.environ["PERSISTENCE_MODULE"] = "eventsourcing.sqlite"
22
- os.environ["CREATE_TABLE"] = "y"
23
- os.environ["SQLITE_DBNAME"] = next(self.uris)
24
-
25
- def tearDown(self) -> None:
26
- del os.environ["PERSISTENCE_MODULE"]
27
- del os.environ["CREATE_TABLE"]
28
- del os.environ["SQLITE_DBNAME"]
29
- super().tearDown()
30
-
31
-
32
- class WithSQLiteInMemory(TestCase):
33
- timeit_number = 30 * TIMEIT_FACTOR
34
- expected_factory_topic = "eventsourcing.sqlite:Factory"
35
-
36
- def setUp(self) -> None:
37
- super().setUp()
38
- os.environ["PERSISTENCE_MODULE"] = "eventsourcing.sqlite"
39
- os.environ["CREATE_TABLE"] = "y"
40
- os.environ["SQLITE_DBNAME"] = "file:memory:?mode=memory&cache=shared"
41
-
42
- def tearDown(self) -> None:
43
- del os.environ["PERSISTENCE_MODULE"]
44
- del os.environ["CREATE_TABLE"]
45
- del os.environ["SQLITE_DBNAME"]
46
- super().tearDown()
47
-
48
-
49
- class TestApplicationWithSQLiteFile(ApplicationTestCase, WithSQLiteFile):
50
- pass
51
-
52
-
53
- # class TestApplicationWithSQLiteInMemory(TestApplication, WithSQLiteInMemory):
54
- # pass
55
-
56
-
57
- class TestExampleApplicationWithSQLiteFile(ExampleApplicationTestCase, WithSQLiteFile):
58
- timeit_number = 30 * TIMEIT_FACTOR
59
- expected_factory_topic = "eventsourcing.sqlite:Factory"
60
-
61
-
62
- class TestExampleApplicationWithSQLiteInMemory(
63
- ExampleApplicationTestCase, WithSQLiteInMemory
64
- ):
65
- timeit_number = 30 * TIMEIT_FACTOR
66
- expected_factory_topic = "eventsourcing.sqlite:Factory"
67
-
68
-
69
- del ApplicationTestCase
70
- del ExampleApplicationTestCase
71
- del WithSQLiteFile
72
- del WithSQLiteInMemory
@@ -1,134 +0,0 @@
1
- from unittest import TestCase
2
-
3
- from eventsourcing.application import Cache, LRUCache
4
-
5
-
6
- class TestCache(TestCase):
7
- def test_put_get(self):
8
- cache = Cache()
9
-
10
- with self.assertRaises(KeyError):
11
- cache.get(1)
12
-
13
- cache.put(1, 1)
14
- self.assertEqual(cache.get(1), 1)
15
-
16
- cache.put(2, 2)
17
- self.assertEqual(1, cache.get(1))
18
- self.assertEqual(2, cache.get(2))
19
-
20
- cache.put(3, 3)
21
- self.assertEqual(3, cache.get(3))
22
- self.assertEqual(2, cache.get(2))
23
- self.assertEqual(1, cache.get(1))
24
-
25
- cache.put(1, 2)
26
- self.assertEqual(2, cache.get(1))
27
- cache.put(1, 3)
28
- self.assertEqual(3, cache.get(1))
29
-
30
- cache.get(1, evict=True)
31
- with self.assertRaises(KeyError):
32
- cache.get(1)
33
-
34
- cache.put(1, None)
35
- with self.assertRaises(KeyError):
36
- cache.get(1)
37
-
38
-
39
- class TestLRUCache(TestCase):
40
- def test_put_get(self):
41
- cache = LRUCache(maxsize=2)
42
-
43
- with self.assertRaises(KeyError):
44
- cache.get(1)
45
-
46
- evicted = cache.put(1, 1)
47
- self.assertEqual(evicted, (None, None))
48
- self.assertEqual(cache.get(1), 1)
49
-
50
- evicted = cache.put(2, 2)
51
- self.assertEqual(evicted, (None, None))
52
- self.assertEqual(1, cache.get(1))
53
- self.assertEqual(2, cache.get(2))
54
-
55
- evicted = cache.put(3, 3)
56
- self.assertEqual(evicted, (1, 1))
57
-
58
- self.assertEqual(3, cache.get(3))
59
- self.assertEqual(2, cache.get(2))
60
-
61
- cache.put(1, 1)
62
- self.assertEqual(1, cache.get(1))
63
- cache.put(1, 2)
64
- self.assertEqual(2, cache.get(1))
65
- cache.put(1, 3)
66
- self.assertEqual(3, cache.get(1))
67
-
68
- def test_put_get_evict_recent(self):
69
- cache = LRUCache(maxsize=3)
70
-
71
- cache.put(1, 1)
72
- self.assertEqual(1, cache.get(1))
73
- self.assertEqual(1, cache.get(1))
74
- self.assertEqual(1, cache.get(1, evict=True))
75
-
76
- with self.assertRaises(KeyError):
77
- self.assertEqual(1, cache.get(1))
78
-
79
- cache.put(1, 1)
80
- cache.put(2, 2)
81
- cache.put(3, 3)
82
- evicted = cache.put(4, 4)
83
- self.assertEqual(evicted, (1, 1))
84
-
85
- self.assertEqual(3, cache.get(3, evict=True))
86
-
87
- evicted = cache.put(5, 5)
88
- self.assertEqual(evicted, (None, None))
89
-
90
- evicted = cache.put(6, 6)
91
- self.assertEqual(evicted, (2, 2))
92
-
93
- evicted = cache.put(7, 7)
94
- self.assertEqual(evicted, (4, 4))
95
-
96
- def test_put_get_evict_oldest(self):
97
- cache = LRUCache(maxsize=3)
98
-
99
- cache.put(1, 1)
100
- cache.put(2, 2)
101
- cache.put(3, 3)
102
- self.assertEqual(1, cache.get(1, evict=True))
103
-
104
- evicted = cache.put(4, 4)
105
- self.assertEqual(evicted, (None, None))
106
-
107
- evicted = cache.put(5, 5)
108
- self.assertEqual(evicted, (2, 2))
109
-
110
- evicted = cache.put(6, 6)
111
- self.assertEqual(evicted, (3, 3))
112
-
113
- evicted = cache.put(7, 7)
114
- self.assertEqual(evicted, (4, 4))
115
-
116
- def test_put_get_evict_newest(self):
117
- cache = LRUCache(maxsize=3)
118
-
119
- cache.put(1, 1)
120
- cache.put(2, 2)
121
- cache.put(3, 3)
122
- self.assertEqual(3, cache.get(3, evict=True))
123
-
124
- evicted = cache.put(4, 4)
125
- self.assertEqual(evicted, (None, None))
126
-
127
- evicted = cache.put(5, 5)
128
- self.assertEqual(evicted, (1, 1))
129
-
130
- evicted = cache.put(6, 6)
131
- self.assertEqual(evicted, (2, 2))
132
-
133
- evicted = cache.put(7, 7)
134
- self.assertEqual(evicted, (4, 4))
@@ -1,162 +0,0 @@
1
- from __future__ import annotations
2
-
3
- from typing import TYPE_CHECKING
4
- from unittest import TestCase
5
- from uuid import NAMESPACE_URL, UUID, uuid4, uuid5
6
-
7
- from eventsourcing.application import Application, EventSourcedLog
8
- from eventsourcing.domain import Aggregate, DomainEvent
9
- from eventsourcing.persistence import (
10
- DatetimeAsISO,
11
- DecimalAsStr,
12
- EventStore,
13
- JSONTranscoder,
14
- Mapper,
15
- UUIDAsHex,
16
- )
17
- from eventsourcing.popo import POPOAggregateRecorder
18
-
19
- if TYPE_CHECKING: # pragma: nocover
20
- from eventsourcing.utils import EnvType
21
-
22
-
23
- class TestEventSourcedLog(TestCase):
24
- def test_logging_aggregate_ids(self) -> None:
25
- class LoggedID(DomainEvent):
26
- aggregate_id: UUID
27
-
28
- transcoder = JSONTranscoder()
29
- transcoder.register(UUIDAsHex())
30
- transcoder.register(DecimalAsStr())
31
- transcoder.register(DatetimeAsISO())
32
-
33
- event_recorder = POPOAggregateRecorder()
34
- event_store = EventStore(
35
- mapper=Mapper(transcoder=transcoder),
36
- recorder=event_recorder,
37
- )
38
-
39
- log: EventSourcedLog[LoggedID] = EventSourcedLog(
40
- events=event_store,
41
- originator_id=uuid5(NAMESPACE_URL, "/aggregates"),
42
- logged_cls=LoggedID,
43
- )
44
- id1 = uuid4()
45
- id2 = uuid4()
46
- id3 = uuid4()
47
-
48
- self.assertEqual(log.get_first(), None)
49
- self.assertEqual(log.get_last(), None)
50
- logged = log.trigger_event(aggregate_id=id1)
51
- event_store.put([logged])
52
- first = log.get_first()
53
- assert first
54
- self.assertEqual(first.aggregate_id, id1)
55
- last = log.get_last()
56
- assert last
57
- self.assertEqual(last.aggregate_id, id1)
58
- logged = log.trigger_event(aggregate_id=id2)
59
- event_store.put([logged])
60
- last = log.get_last()
61
- assert last
62
- self.assertEqual(last.aggregate_id, id2)
63
- logged = log.trigger_event(aggregate_id=id3, next_originator_version=3)
64
- event_store.put([logged])
65
- last = log.get_last()
66
- assert last
67
- self.assertEqual(last.aggregate_id, id3)
68
- first = log.get_first()
69
- assert first
70
- self.assertEqual(first.aggregate_id, id1)
71
-
72
- ids = [e.aggregate_id for e in log.get()]
73
- self.assertEqual(ids, [id1, id2, id3])
74
-
75
- ids = [e.aggregate_id for e in log.get(gt=1)]
76
- self.assertEqual(ids, [id2, id3])
77
-
78
- ids = [e.aggregate_id for e in log.get(lte=2)]
79
- self.assertEqual(ids, [id1, id2])
80
-
81
- ids = [e.aggregate_id for e in log.get(limit=1)]
82
- self.assertEqual(ids, [id1])
83
-
84
- ids = [e.aggregate_id for e in log.get(desc=True)]
85
- self.assertEqual(ids, [id3, id2, id1])
86
-
87
- def test_with_application(self) -> None:
88
- class LoggedID(DomainEvent):
89
- aggregate_id: UUID
90
-
91
- class MyApplication(Application):
92
- def __init__(self, env: EnvType | None = None) -> None:
93
- super().__init__(env=env)
94
- self.aggregate_log = EventSourcedLog(
95
- events=self.events,
96
- originator_id=uuid5(NAMESPACE_URL, "/aggregates"),
97
- logged_cls=LoggedID,
98
- )
99
-
100
- def create_aggregate(self) -> UUID:
101
- aggregate = Aggregate()
102
- logged_id = self.aggregate_log.trigger_event(aggregate_id=aggregate.id)
103
- self.save(aggregate, logged_id)
104
- return aggregate.id
105
-
106
- app = MyApplication()
107
-
108
- self.assertEqual(app.aggregate_log.get_last(), None)
109
-
110
- aggregate1_id = app.create_aggregate()
111
- last = app.aggregate_log.get_last()
112
- assert last
113
- self.assertEqual(last.aggregate_id, aggregate1_id)
114
-
115
- aggregate2_id = app.create_aggregate()
116
- last = app.aggregate_log.get_last()
117
- assert last
118
- self.assertEqual(last.aggregate_id, aggregate2_id)
119
-
120
- aggregate_ids = [i.aggregate_id for i in app.aggregate_log.get()]
121
- self.assertEqual(aggregate_ids, [aggregate1_id, aggregate2_id])
122
-
123
- def test_subclasses(self) -> None:
124
- transcoder = JSONTranscoder()
125
- transcoder.register(UUIDAsHex())
126
- transcoder.register(DecimalAsStr())
127
- transcoder.register(DatetimeAsISO())
128
-
129
- event_recorder = POPOAggregateRecorder()
130
- event_store = EventStore(
131
- mapper=Mapper(transcoder=transcoder),
132
- recorder=event_recorder,
133
- )
134
-
135
- class TransactionLogEvent(DomainEvent):
136
- pass
137
-
138
- class AccountCredited(TransactionLogEvent):
139
- pass
140
-
141
- class AccountDebited(TransactionLogEvent):
142
- pass
143
-
144
- # Subclass EventSourcedLog.
145
- class TransactionLog(EventSourcedLog[TransactionLogEvent]):
146
- def account_credited(self) -> AccountCredited:
147
- return self._trigger_event(logged_cls=AccountCredited)
148
-
149
- def account_debited(self) -> AccountDebited:
150
- return self._trigger_event(logged_cls=AccountDebited)
151
-
152
- transaction_log = TransactionLog(
153
- events=event_store,
154
- originator_id=uuid5(NAMESPACE_URL, "/aggregates"),
155
- logged_cls=TransactionLogEvent,
156
- )
157
-
158
- account_credited = transaction_log.account_credited()
159
- self.assertIsInstance(account_credited, AccountCredited)
160
-
161
- account_debited = transaction_log.account_debited()
162
- self.assertIsInstance(account_debited, AccountDebited)
@@ -1,232 +0,0 @@
1
- from unittest.case import TestCase
2
- from uuid import uuid4
3
-
4
- from eventsourcing.application import LocalNotificationLog
5
- from eventsourcing.persistence import StoredEvent
6
- from eventsourcing.sqlite import SQLiteApplicationRecorder, SQLiteDatastore
7
-
8
-
9
- class TestNotificationLog(TestCase):
10
- def test_get_section(self):
11
- recorder = SQLiteApplicationRecorder(SQLiteDatastore(":memory:"))
12
- recorder.create_table()
13
-
14
- # Construct notification log.
15
- notification_log = LocalNotificationLog(recorder, section_size=5)
16
-
17
- # Get the "current" section of log.
18
- section = notification_log["1,10"]
19
- self.assertEqual(len(section.items), 0) # event notifications
20
- self.assertEqual(section.id, None)
21
- self.assertEqual(section.next_id, None)
22
-
23
- # Write 5 events.
24
- originator_id = uuid4()
25
- for i in range(5):
26
- stored_event = StoredEvent(
27
- originator_id=originator_id,
28
- originator_version=i,
29
- topic="topic",
30
- state=b"state",
31
- )
32
- recorder.insert_events([stored_event])
33
-
34
- # Get the "head" section of log.
35
- section = notification_log["1,10"]
36
- self.assertEqual(len(section.items), 5) # event notifications
37
- self.assertEqual(section.items[0].id, 1)
38
- self.assertEqual(section.items[1].id, 2)
39
- self.assertEqual(section.items[2].id, 3)
40
- self.assertEqual(section.items[3].id, 4)
41
- self.assertEqual(section.items[4].id, 5)
42
- self.assertEqual(section.id, "1,5")
43
- self.assertEqual(section.next_id, "6,10")
44
-
45
- # Get the "1,5" section of log.
46
- section = notification_log["1,5"]
47
- self.assertEqual(len(section.items), 5) # event notifications
48
- self.assertEqual(section.items[0].id, 1)
49
- self.assertEqual(section.items[1].id, 2)
50
- self.assertEqual(section.items[2].id, 3)
51
- self.assertEqual(section.items[3].id, 4)
52
- self.assertEqual(section.items[4].id, 5)
53
- self.assertEqual(section.id, "1,5")
54
- self.assertEqual(section.next_id, "6,10")
55
-
56
- # Get the next section of log.
57
- section = notification_log["6,10"]
58
- self.assertEqual(len(section.items), 0) # event notifications
59
- self.assertEqual(section.id, None)
60
- self.assertEqual(section.next_id, None)
61
-
62
- # Write 4 events.
63
- originator_id = uuid4()
64
- for i in range(4):
65
- stored_event = StoredEvent(
66
- originator_id=originator_id,
67
- originator_version=i,
68
- topic="topic",
69
- state=b"state",
70
- )
71
- recorder.insert_events([stored_event])
72
-
73
- # Get the next section of log.
74
- section = notification_log["6,10"]
75
- self.assertEqual(len(section.items), 4) # event notifications
76
- self.assertEqual(section.items[0].id, 6)
77
- self.assertEqual(section.items[1].id, 7)
78
- self.assertEqual(section.items[2].id, 8)
79
- self.assertEqual(section.items[3].id, 9)
80
- self.assertEqual(section.id, "6,9")
81
- self.assertEqual(section.next_id, None)
82
-
83
- # Start at non-regular section start.
84
- section = notification_log["3,7"]
85
- self.assertEqual(len(section.items), 5) # event notifications
86
- self.assertEqual(section.items[0].id, 3)
87
- self.assertEqual(section.items[1].id, 4)
88
- self.assertEqual(section.items[2].id, 5)
89
- self.assertEqual(section.items[3].id, 6)
90
- self.assertEqual(section.items[4].id, 7)
91
- self.assertEqual(section.id, "3,7")
92
- self.assertEqual(section.next_id, "8,12")
93
-
94
- # Notification log limits section size.
95
- section = notification_log["3,10"]
96
- self.assertEqual(len(section.items), 5) # event notifications
97
- self.assertEqual(section.items[0].id, 3)
98
- self.assertEqual(section.items[1].id, 4)
99
- self.assertEqual(section.items[2].id, 5)
100
- self.assertEqual(section.items[3].id, 6)
101
- self.assertEqual(section.items[4].id, 7)
102
- self.assertEqual(section.id, "3,7")
103
- self.assertEqual(section.next_id, "8,12")
104
-
105
- # Reader limits section size.
106
- section = notification_log["3,4"]
107
- self.assertEqual(len(section.items), 2) # event notifications
108
- self.assertEqual(section.items[0].id, 3)
109
- self.assertEqual(section.items[1].id, 4)
110
- self.assertEqual(section.id, "3,4")
111
- self.assertEqual(section.next_id, "5,6")
112
-
113
- # Meaningless section ID.
114
- section = notification_log["3,2"]
115
- self.assertEqual(len(section.items), 0) # event notifications
116
- self.assertEqual(section.id, None)
117
- self.assertEqual(section.next_id, None)
118
-
119
- # # Numbers below 1.
120
- # section = notification_log["-3,0"]
121
- # self.assertEqual(
122
- # len(section.items), 4
123
- # ) # event notifications
124
- # self.assertEqual(section.items[0].id, 6)
125
- # self.assertEqual(section.items[1].id, 7)
126
- # self.assertEqual(section.items[2].id, 8)
127
- # self.assertEqual(section.items[3].id, 9)
128
- # self.assertEqual(section.section_id, "6,9")
129
- # self.assertEqual(section.next_id, None)
130
- #
131
- # section = notification_log["-4,0"]
132
- # self.assertEqual(
133
- # len(section.items), 5
134
- # ) # event notifications
135
- # self.assertEqual(section.items[0].id, 5)
136
- # self.assertEqual(section.items[1].id, 6)
137
- # self.assertEqual(section.items[2].id, 7)
138
- # self.assertEqual(section.items[3].id, 8)
139
- # self.assertEqual(section.items[4].id, 9)
140
- # self.assertEqual(section.section_id, "5,9")
141
- # self.assertEqual(section.next_id, "10,14")
142
- #
143
- # section = notification_log["-4,-1"]
144
- # self.assertEqual(
145
- # len(section.items), 4
146
- # ) # event notifications
147
- # self.assertEqual(section.items[0].id, 5)
148
- # self.assertEqual(section.items[1].id, 6)
149
- # self.assertEqual(section.items[2].id, 7)
150
- # self.assertEqual(section.items[3].id, 8)
151
- # self.assertEqual(section.section_id, "5,8")
152
- # self.assertEqual(section.next_id, "9,12")
153
-
154
- def test_select(self):
155
- recorder = SQLiteApplicationRecorder(SQLiteDatastore(":memory:"))
156
- recorder.create_table()
157
-
158
- # Construct notification log.
159
- notification_log = LocalNotificationLog(recorder, section_size=10)
160
-
161
- # Select start 1, limit 10
162
- notifications = notification_log.select(1, 10)
163
- self.assertEqual(len(notifications), 0)
164
-
165
- # Write 5 events.
166
- originator_id = uuid4()
167
- for i in range(5):
168
- stored_event = StoredEvent(
169
- originator_id=originator_id,
170
- originator_version=i,
171
- topic="topic",
172
- state=b"state",
173
- )
174
- recorder.insert_events([stored_event])
175
-
176
- # Select start 1, limit 10
177
- notifications = notification_log.select(1, 5)
178
- self.assertEqual(len(notifications), 5)
179
- self.assertEqual(notifications[0].id, 1)
180
- self.assertEqual(notifications[1].id, 2)
181
- self.assertEqual(notifications[2].id, 3)
182
- self.assertEqual(notifications[3].id, 4)
183
- self.assertEqual(notifications[4].id, 5)
184
-
185
- # Select start 1, limit 10
186
- notifications = notification_log.select(1, 5)
187
- self.assertEqual(len(notifications), 5)
188
- self.assertEqual(notifications[0].id, 1)
189
- self.assertEqual(notifications[1].id, 2)
190
- self.assertEqual(notifications[2].id, 3)
191
- self.assertEqual(notifications[3].id, 4)
192
- self.assertEqual(notifications[4].id, 5)
193
-
194
- # Select start 6, limit 5
195
- notifications = notification_log.select(6, 5)
196
- self.assertEqual(len(notifications), 0)
197
-
198
- # Write 4 events.
199
- originator_id = uuid4()
200
- for i in range(4):
201
- stored_event = StoredEvent(
202
- originator_id=originator_id,
203
- originator_version=i,
204
- topic="topic",
205
- state=b"state",
206
- )
207
- recorder.insert_events([stored_event])
208
-
209
- # Select start 6, limit 5
210
- notifications = notification_log.select(6, 5)
211
- self.assertEqual(len(notifications), 4) # event notifications
212
- self.assertEqual(notifications[0].id, 6)
213
- self.assertEqual(notifications[1].id, 7)
214
- self.assertEqual(notifications[2].id, 8)
215
- self.assertEqual(notifications[3].id, 9)
216
-
217
- # Select start 3, limit 5
218
- notifications = notification_log.select(3, 5)
219
- self.assertEqual(len(notifications), 5) # event notifications
220
- self.assertEqual(notifications[0].id, 3)
221
- self.assertEqual(notifications[1].id, 4)
222
- self.assertEqual(notifications[2].id, 5)
223
- self.assertEqual(notifications[3].id, 6)
224
- self.assertEqual(notifications[4].id, 7)
225
-
226
- # Notification log limits limit.
227
- # Select start 1, limit 20
228
- with self.assertRaises(ValueError) as cm:
229
- notification_log.select(1, 20)
230
- self.assertEqual(
231
- cm.exception.args[0], "Requested limit 20 greater than section size 10"
232
- )