event_system 0.1.0
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.
- checksums.yaml +7 -0
- data/.rspec +3 -0
- data/README.md +362 -0
- data/Rakefile +4 -0
- data/docs/event_visualizations/example_timeline.html +142 -0
- data/docs/example_logs/events_20251027_151744.jsonl +3 -0
- data/docs/example_logs/events_20251027_151802.jsonl +3 -0
- data/docs/examples/basic_usage.rb +64 -0
- data/exe/event_system +139 -0
- data/lib/event_system/configuration.rb +125 -0
- data/lib/event_system/event.rb +139 -0
- data/lib/event_system/event_manager.rb +191 -0
- data/lib/event_system/event_subscriber.rb +29 -0
- data/lib/event_system/storage/base.rb +64 -0
- data/lib/event_system/storage/file_store.rb +187 -0
- data/lib/event_system/storage/memory_store.rb +134 -0
- data/lib/event_system/version.rb +5 -0
- data/lib/event_system/visualization/timeline_generator.rb +237 -0
- data/lib/event_system.rb +37 -0
- data/spec/event_system/configuration_spec.rb +197 -0
- data/spec/event_system/event_manager_spec.rb +341 -0
- data/spec/event_system/event_spec.rb +193 -0
- data/spec/event_system/event_subscriber_spec.rb +295 -0
- data/spec/event_system/storage/file_store_spec.rb +341 -0
- data/spec/event_system/storage/memory_store_spec.rb +248 -0
- data/spec/event_system/visualization/timeline_generator_spec.rb +252 -0
- data/spec/event_system_spec.rb +57 -0
- data/spec/integration/readme_examples_spec.rb +447 -0
- data/spec/spec_helper.rb +80 -0
- metadata +171 -0
|
@@ -0,0 +1,447 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'spec_helper'
|
|
4
|
+
|
|
5
|
+
RSpec.describe 'README Examples Integration Tests' do
|
|
6
|
+
describe 'Basic Usage Example' do
|
|
7
|
+
it 'demonstrates basic event creation and publishing' do
|
|
8
|
+
# Create an event manager
|
|
9
|
+
manager = EventSystem.create_manager
|
|
10
|
+
|
|
11
|
+
# Create and publish an event
|
|
12
|
+
event = manager.publish_event(:user_created, self, { user_id: 123, name: "John Doe" })
|
|
13
|
+
|
|
14
|
+
expect(event).to be_a(EventSystem::Event)
|
|
15
|
+
expect(event.type).to eq('user_created')
|
|
16
|
+
expect(event.data[:user_id]).to eq(123)
|
|
17
|
+
expect(event.data[:name]).to eq('John Doe')
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
it 'demonstrates event subscription' do
|
|
21
|
+
manager = EventSystem.create_manager
|
|
22
|
+
|
|
23
|
+
# Subscribe to events
|
|
24
|
+
class UserNotifier
|
|
25
|
+
include EventSystem::EventSubscriber
|
|
26
|
+
|
|
27
|
+
attr_reader :events_received
|
|
28
|
+
|
|
29
|
+
def initialize
|
|
30
|
+
@events_received = []
|
|
31
|
+
end
|
|
32
|
+
|
|
33
|
+
def handle_event(event)
|
|
34
|
+
@events_received << event
|
|
35
|
+
end
|
|
36
|
+
end
|
|
37
|
+
|
|
38
|
+
notifier = UserNotifier.new
|
|
39
|
+
manager.subscribe(:user_created, notifier)
|
|
40
|
+
|
|
41
|
+
# Publish event
|
|
42
|
+
manager.publish_event(:user_created, self, { user_id: 123, name: "John Doe" })
|
|
43
|
+
|
|
44
|
+
expect(notifier.events_received.length).to eq(1)
|
|
45
|
+
expect(notifier.events_received.first.type).to eq('user_created')
|
|
46
|
+
end
|
|
47
|
+
end
|
|
48
|
+
|
|
49
|
+
describe 'Configuration Example' do
|
|
50
|
+
it 'demonstrates file storage configuration' do
|
|
51
|
+
# Configure with file storage
|
|
52
|
+
config = {
|
|
53
|
+
storage_type: :file,
|
|
54
|
+
storage_options: { directory: @temp_dir },
|
|
55
|
+
session_id: "my_app_session"
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
manager = EventSystem.create_manager(config)
|
|
59
|
+
|
|
60
|
+
expect(manager.config.storage_type).to eq(:file)
|
|
61
|
+
expect(manager.config.storage_options[:directory]).to eq(@temp_dir)
|
|
62
|
+
expect(manager.config.session_id).to eq("my_app_session")
|
|
63
|
+
end
|
|
64
|
+
|
|
65
|
+
it 'demonstrates memory storage for testing' do
|
|
66
|
+
manager = EventSystem.create_manager(storage_type: :memory)
|
|
67
|
+
expect(manager.config.storage_type).to eq(:memory)
|
|
68
|
+
end
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
describe 'Event Creation Example' do
|
|
72
|
+
it 'demonstrates manual event creation' do
|
|
73
|
+
manager = EventSystem.create_manager
|
|
74
|
+
|
|
75
|
+
# Create an event manually
|
|
76
|
+
event = EventSystem.create_event(:order_placed, self, {
|
|
77
|
+
order_id: 456,
|
|
78
|
+
customer_id: 789,
|
|
79
|
+
amount: 99.99
|
|
80
|
+
})
|
|
81
|
+
|
|
82
|
+
expect(event.type).to eq('order_placed')
|
|
83
|
+
expect(event.data[:order_id]).to eq(456)
|
|
84
|
+
expect(event.data[:customer_id]).to eq(789)
|
|
85
|
+
expect(event.data[:amount]).to eq(99.99)
|
|
86
|
+
|
|
87
|
+
# Publish the event
|
|
88
|
+
manager.publish(event)
|
|
89
|
+
end
|
|
90
|
+
end
|
|
91
|
+
|
|
92
|
+
describe 'Event Subscribers Example' do
|
|
93
|
+
it 'demonstrates order processing with multiple event types' do
|
|
94
|
+
manager = EventSystem.create_manager
|
|
95
|
+
|
|
96
|
+
class OrderProcessor
|
|
97
|
+
include EventSystem::EventSubscriber
|
|
98
|
+
|
|
99
|
+
attr_reader :processed_orders, :fulfilled_orders
|
|
100
|
+
|
|
101
|
+
def initialize
|
|
102
|
+
@processed_orders = []
|
|
103
|
+
@fulfilled_orders = []
|
|
104
|
+
end
|
|
105
|
+
|
|
106
|
+
def handle_event(event)
|
|
107
|
+
case event.type
|
|
108
|
+
when 'order_placed'
|
|
109
|
+
process_order(event.data)
|
|
110
|
+
when 'payment_received'
|
|
111
|
+
fulfill_order(event.data)
|
|
112
|
+
end
|
|
113
|
+
end
|
|
114
|
+
|
|
115
|
+
private
|
|
116
|
+
|
|
117
|
+
def process_order(data)
|
|
118
|
+
@processed_orders << data
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
def fulfill_order(data)
|
|
122
|
+
@fulfilled_orders << data
|
|
123
|
+
end
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
processor = OrderProcessor.new
|
|
127
|
+
manager.subscribe(:order_placed, processor)
|
|
128
|
+
manager.subscribe(:payment_received, processor)
|
|
129
|
+
|
|
130
|
+
# Publish events
|
|
131
|
+
manager.publish_event(:order_placed, 'OrderService', { order_id: 123, amount: 50.0 })
|
|
132
|
+
manager.publish_event(:payment_received, 'PaymentService', { order_id: 123, amount: 50.0 })
|
|
133
|
+
|
|
134
|
+
expect(processor.processed_orders.length).to eq(1)
|
|
135
|
+
expect(processor.fulfilled_orders.length).to eq(1)
|
|
136
|
+
expect(processor.processed_orders.first[:order_id]).to eq(123)
|
|
137
|
+
end
|
|
138
|
+
|
|
139
|
+
it 'demonstrates subscribe_all functionality' do
|
|
140
|
+
manager = EventSystem.create_manager
|
|
141
|
+
|
|
142
|
+
class UniversalSubscriber
|
|
143
|
+
include EventSystem::EventSubscriber
|
|
144
|
+
|
|
145
|
+
attr_reader :all_events
|
|
146
|
+
|
|
147
|
+
def initialize
|
|
148
|
+
@all_events = []
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
def handle_event(event)
|
|
152
|
+
@all_events << event
|
|
153
|
+
end
|
|
154
|
+
end
|
|
155
|
+
|
|
156
|
+
subscriber = UniversalSubscriber.new
|
|
157
|
+
manager.subscribe_all(subscriber)
|
|
158
|
+
|
|
159
|
+
# Publish different event types
|
|
160
|
+
manager.publish_event(:event1, 'Source1', { data: 'value1' })
|
|
161
|
+
manager.publish_event(:event2, 'Source2', { data: 'value2' })
|
|
162
|
+
|
|
163
|
+
expect(subscriber.all_events.length).to eq(2)
|
|
164
|
+
expect(subscriber.all_events.map(&:type)).to include('event1', 'event2')
|
|
165
|
+
end
|
|
166
|
+
end
|
|
167
|
+
|
|
168
|
+
describe 'Event Querying Example' do
|
|
169
|
+
it 'demonstrates various querying capabilities' do
|
|
170
|
+
manager = create_file_manager
|
|
171
|
+
|
|
172
|
+
# Publish various events
|
|
173
|
+
manager.publish_event(:order_placed, 'OrderService', { order_id: 1, amount: 100 })
|
|
174
|
+
manager.publish_event(:order_placed, 'OrderService', { order_id: 2, amount: 200 })
|
|
175
|
+
manager.publish_event(:user_created, 'UserService', { user_id: 1, name: 'John' })
|
|
176
|
+
|
|
177
|
+
# Query events by type
|
|
178
|
+
orders = manager.query_events(type: 'order_placed')
|
|
179
|
+
expect(orders.length).to eq(2)
|
|
180
|
+
expect(orders.all? { |e| e.type == 'order_placed' }).to be true
|
|
181
|
+
|
|
182
|
+
# Query events by time range
|
|
183
|
+
start_time = Time.now - 3600 # 1 hour in seconds
|
|
184
|
+
end_time = Time.now + 3600 # 1 hour in seconds
|
|
185
|
+
recent_events = manager.query_events(start_time: start_time, end_time: end_time)
|
|
186
|
+
expect(recent_events.length).to eq(3)
|
|
187
|
+
|
|
188
|
+
# Query with limit
|
|
189
|
+
last_2_events = manager.query_events(limit: 2)
|
|
190
|
+
expect(last_2_events.length).to eq(2)
|
|
191
|
+
|
|
192
|
+
# Query from specific session
|
|
193
|
+
session_events = manager.query_events(session_id: manager.current_session)
|
|
194
|
+
expect(session_events.length).to eq(3)
|
|
195
|
+
end
|
|
196
|
+
end
|
|
197
|
+
|
|
198
|
+
describe 'Storage Backends Example' do
|
|
199
|
+
it 'demonstrates memory storage for testing' do
|
|
200
|
+
manager = EventSystem.create_manager(storage_type: :memory)
|
|
201
|
+
|
|
202
|
+
# Switch sessions
|
|
203
|
+
manager.switch_session('test_session_1')
|
|
204
|
+
manager.publish_event(:test_event, self, { data: 'test' })
|
|
205
|
+
|
|
206
|
+
# Create new session
|
|
207
|
+
new_session = manager.create_session('my_new_session')
|
|
208
|
+
expect(new_session).to eq('my_new_session')
|
|
209
|
+
expect(manager.current_session).to eq('my_new_session')
|
|
210
|
+
end
|
|
211
|
+
|
|
212
|
+
it 'demonstrates file storage persistence' do
|
|
213
|
+
config = {
|
|
214
|
+
storage_type: :file,
|
|
215
|
+
storage_options: { directory: @temp_dir }
|
|
216
|
+
}
|
|
217
|
+
manager = EventSystem.create_manager(config)
|
|
218
|
+
|
|
219
|
+
# Events are automatically saved to JSONL files
|
|
220
|
+
manager.publish_event(:user_action, self, { action: 'login' })
|
|
221
|
+
|
|
222
|
+
# Verify file was created
|
|
223
|
+
session_file = File.join(@temp_dir, "events_#{manager.current_session}.jsonl")
|
|
224
|
+
expect(File.exist?(session_file)).to be true
|
|
225
|
+
|
|
226
|
+
# Verify content
|
|
227
|
+
content = File.read(session_file)
|
|
228
|
+
expect(content).to include('user_action')
|
|
229
|
+
expect(content).to include('login')
|
|
230
|
+
end
|
|
231
|
+
end
|
|
232
|
+
|
|
233
|
+
describe 'Visualization Example' do
|
|
234
|
+
it 'demonstrates timeline generation' do
|
|
235
|
+
manager = create_file_manager
|
|
236
|
+
|
|
237
|
+
# Add some events
|
|
238
|
+
manager.publish_event(:user_created, 'UserService', { user_id: 123, name: 'John Doe' })
|
|
239
|
+
manager.publish_event(:order_placed, 'OrderService', { order_id: 456, amount: 99.99 })
|
|
240
|
+
|
|
241
|
+
# Generate timeline visualization
|
|
242
|
+
generator = EventSystem::Visualization::TimelineGenerator.new(manager.storage)
|
|
243
|
+
html_file = generator.generate_timeline(nil, 'timeline.html')
|
|
244
|
+
|
|
245
|
+
expect(html_file).to be_a(String)
|
|
246
|
+
expect(File.exist?(html_file)).to be true
|
|
247
|
+
expect(html_file).to end_with('.html')
|
|
248
|
+
end
|
|
249
|
+
|
|
250
|
+
it 'demonstrates event summary' do
|
|
251
|
+
manager = create_file_manager
|
|
252
|
+
|
|
253
|
+
# Add events
|
|
254
|
+
manager.publish_event(:user_created, 'UserService', { user_id: 1 })
|
|
255
|
+
manager.publish_event(:user_created, 'UserService', { user_id: 2 })
|
|
256
|
+
manager.publish_event(:order_placed, 'OrderService', { order_id: 1 })
|
|
257
|
+
|
|
258
|
+
generator = EventSystem::Visualization::TimelineGenerator.new(manager.storage)
|
|
259
|
+
summary = generator.event_summary
|
|
260
|
+
|
|
261
|
+
expect(summary).to be_a(Hash)
|
|
262
|
+
expect(summary['user_created']).to eq(2)
|
|
263
|
+
expect(summary['order_placed']).to eq(1)
|
|
264
|
+
end
|
|
265
|
+
|
|
266
|
+
it 'demonstrates timeline data export' do
|
|
267
|
+
manager = create_file_manager
|
|
268
|
+
|
|
269
|
+
manager.publish_event(:test_event, 'TestSource', { key: 'value' })
|
|
270
|
+
|
|
271
|
+
generator = EventSystem::Visualization::TimelineGenerator.new(manager.storage)
|
|
272
|
+
timeline_data = generator.timeline_data
|
|
273
|
+
|
|
274
|
+
expect(timeline_data).to be_an(Array)
|
|
275
|
+
expect(timeline_data.length).to eq(1)
|
|
276
|
+
|
|
277
|
+
event_data = timeline_data.first
|
|
278
|
+
expect(event_data[:type]).to eq('test_event')
|
|
279
|
+
expect(event_data[:source]).to eq('TestSource')
|
|
280
|
+
expect(event_data[:data][:key]).to eq('value')
|
|
281
|
+
end
|
|
282
|
+
end
|
|
283
|
+
|
|
284
|
+
describe 'Advanced Configuration Example' do
|
|
285
|
+
it 'demonstrates custom configuration' do
|
|
286
|
+
# Custom configuration
|
|
287
|
+
config = EventSystem::Configuration.new
|
|
288
|
+
config.storage_type = :file
|
|
289
|
+
config.storage_options = { directory: @temp_dir }
|
|
290
|
+
config.session_id = 'production_session'
|
|
291
|
+
config.auto_flush = true
|
|
292
|
+
|
|
293
|
+
manager = EventSystem.create_manager(config)
|
|
294
|
+
|
|
295
|
+
expect(manager.config.storage_type).to eq(:file)
|
|
296
|
+
expect(manager.config.storage_options[:directory]).to eq(@temp_dir)
|
|
297
|
+
expect(manager.config.session_id).to eq('production_session')
|
|
298
|
+
expect(manager.config.auto_flush).to be true
|
|
299
|
+
end
|
|
300
|
+
|
|
301
|
+
it 'demonstrates custom logger configuration' do
|
|
302
|
+
require 'logger'
|
|
303
|
+
log_io = StringIO.new
|
|
304
|
+
config = EventSystem::Configuration.new
|
|
305
|
+
config.logger = Logger.new(log_io)
|
|
306
|
+
|
|
307
|
+
manager = EventSystem.create_manager(config)
|
|
308
|
+
|
|
309
|
+
# Publish an event to trigger logging
|
|
310
|
+
manager.publish_event(:test_event, self, { data: 'test' })
|
|
311
|
+
|
|
312
|
+
# Check that logging occurred
|
|
313
|
+
log_content = log_io.string
|
|
314
|
+
expect(log_content).to include('EventSystem initialized')
|
|
315
|
+
expect(log_content).to include('Publishing event')
|
|
316
|
+
end
|
|
317
|
+
end
|
|
318
|
+
|
|
319
|
+
describe 'Error Handling Example' do
|
|
320
|
+
it 'demonstrates safe subscriber error handling' do
|
|
321
|
+
manager = EventSystem.create_manager
|
|
322
|
+
|
|
323
|
+
class SafeSubscriber
|
|
324
|
+
include EventSystem::EventSubscriber
|
|
325
|
+
|
|
326
|
+
attr_reader :errors_handled
|
|
327
|
+
|
|
328
|
+
def initialize
|
|
329
|
+
@errors_handled = []
|
|
330
|
+
end
|
|
331
|
+
|
|
332
|
+
def handle_event(event)
|
|
333
|
+
if event.data[:should_fail]
|
|
334
|
+
raise StandardError, 'Test error'
|
|
335
|
+
end
|
|
336
|
+
end
|
|
337
|
+
end
|
|
338
|
+
|
|
339
|
+
safe_subscriber = SafeSubscriber.new
|
|
340
|
+
manager.subscribe(:test_event, safe_subscriber)
|
|
341
|
+
|
|
342
|
+
# Publish event that should not fail
|
|
343
|
+
manager.publish_event(:test_event, self, { should_fail: false })
|
|
344
|
+
|
|
345
|
+
# Publish event that should fail (but be handled gracefully)
|
|
346
|
+
expect {
|
|
347
|
+
manager.publish_event(:test_event, self, { should_fail: true })
|
|
348
|
+
}.not_to raise_error
|
|
349
|
+
end
|
|
350
|
+
end
|
|
351
|
+
|
|
352
|
+
describe 'Web Application Example' do
|
|
353
|
+
it 'demonstrates web application event handling' do
|
|
354
|
+
class WebApp
|
|
355
|
+
attr_reader :event_manager, :events_logged
|
|
356
|
+
|
|
357
|
+
def initialize
|
|
358
|
+
@event_manager = EventSystem.create_manager(
|
|
359
|
+
storage_type: :file,
|
|
360
|
+
storage_options: { directory: @temp_dir }
|
|
361
|
+
)
|
|
362
|
+
@events_logged = []
|
|
363
|
+
|
|
364
|
+
# Subscribe to web events
|
|
365
|
+
@event_manager.subscribe(:request_received, self)
|
|
366
|
+
@event_manager.subscribe(:response_sent, self)
|
|
367
|
+
end
|
|
368
|
+
|
|
369
|
+
def handle_request(request)
|
|
370
|
+
@event_manager.publish_event(:request_received, self, {
|
|
371
|
+
path: request[:path],
|
|
372
|
+
method: request[:method],
|
|
373
|
+
ip: request[:ip]
|
|
374
|
+
})
|
|
375
|
+
end
|
|
376
|
+
|
|
377
|
+
def handle_event(event)
|
|
378
|
+
@events_logged << event
|
|
379
|
+
end
|
|
380
|
+
end
|
|
381
|
+
|
|
382
|
+
web_app = WebApp.new
|
|
383
|
+
|
|
384
|
+
# Simulate request
|
|
385
|
+
request = { path: '/api/users', method: 'GET', ip: '127.0.0.1' }
|
|
386
|
+
web_app.handle_request(request)
|
|
387
|
+
|
|
388
|
+
expect(web_app.events_logged.length).to eq(1)
|
|
389
|
+
event = web_app.events_logged.first
|
|
390
|
+
expect(event.type).to eq('request_received')
|
|
391
|
+
expect(event.data[:path]).to eq('/api/users')
|
|
392
|
+
expect(event.data[:method]).to eq('GET')
|
|
393
|
+
end
|
|
394
|
+
end
|
|
395
|
+
|
|
396
|
+
describe 'Microservice Communication Example' do
|
|
397
|
+
it 'demonstrates microservice event communication' do
|
|
398
|
+
class OrderService
|
|
399
|
+
attr_reader :event_manager, :orders_fulfilled
|
|
400
|
+
|
|
401
|
+
def initialize
|
|
402
|
+
@event_manager = EventSystem.create_manager
|
|
403
|
+
@orders_fulfilled = []
|
|
404
|
+
@event_manager.subscribe(:payment_processed, self)
|
|
405
|
+
end
|
|
406
|
+
|
|
407
|
+
def place_order(order_data)
|
|
408
|
+
@event_manager.publish_event(:order_created, self, order_data)
|
|
409
|
+
end
|
|
410
|
+
|
|
411
|
+
def handle_event(event)
|
|
412
|
+
if event.type == 'payment_processed'
|
|
413
|
+
fulfill_order(event.data[:order_id])
|
|
414
|
+
end
|
|
415
|
+
end
|
|
416
|
+
|
|
417
|
+
private
|
|
418
|
+
|
|
419
|
+
def fulfill_order(order_id)
|
|
420
|
+
@orders_fulfilled << order_id
|
|
421
|
+
end
|
|
422
|
+
end
|
|
423
|
+
|
|
424
|
+
order_service = OrderService.new
|
|
425
|
+
|
|
426
|
+
# Place an order
|
|
427
|
+
order_service.place_order({ customer_id: 123, amount: 100 })
|
|
428
|
+
|
|
429
|
+
# Simulate payment processing
|
|
430
|
+
order_service.event_manager.publish_event(:payment_processed, 'PaymentService', { order_id: 1 })
|
|
431
|
+
|
|
432
|
+
expect(order_service.orders_fulfilled).to include(1)
|
|
433
|
+
end
|
|
434
|
+
end
|
|
435
|
+
|
|
436
|
+
describe 'Testing Example' do
|
|
437
|
+
it 'demonstrates testing with memory storage' do
|
|
438
|
+
event_manager = EventSystem.create_manager(storage_type: :memory)
|
|
439
|
+
|
|
440
|
+
# Mock the publish_event method to verify it's called
|
|
441
|
+
expect(event_manager).to receive(:publish_event).with(:order_created, anything, anything)
|
|
442
|
+
|
|
443
|
+
# Simulate service behavior
|
|
444
|
+
event_manager.publish_event(:order_created, 'TestService', { customer_id: 123 })
|
|
445
|
+
end
|
|
446
|
+
end
|
|
447
|
+
end
|
data/spec/spec_helper.rb
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
# frozen_string_literal: true
|
|
2
|
+
|
|
3
|
+
require 'bundler/setup'
|
|
4
|
+
require 'event_system'
|
|
5
|
+
require 'rspec'
|
|
6
|
+
require 'tempfile'
|
|
7
|
+
require 'fileutils'
|
|
8
|
+
|
|
9
|
+
RSpec.configure do |config|
|
|
10
|
+
# Enable flags like --only-failures and --next-failure
|
|
11
|
+
config.example_status_persistence_file_path = '.rspec_status'
|
|
12
|
+
|
|
13
|
+
# Disable RSpec exposing methods globally on `Module` and `main`
|
|
14
|
+
config.disable_monkey_patching!
|
|
15
|
+
|
|
16
|
+
config.expect_with :rspec do |c|
|
|
17
|
+
c.syntax = :expect
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
# Clean up temporary files after each test
|
|
21
|
+
config.after(:each) do
|
|
22
|
+
# Clean up any temporary files created during tests
|
|
23
|
+
if defined?(@temp_dir) && @temp_dir && Dir.exist?(@temp_dir)
|
|
24
|
+
FileUtils.rm_rf(@temp_dir)
|
|
25
|
+
end
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
# Helper method to create a temporary directory for file storage tests
|
|
29
|
+
config.before(:each) do
|
|
30
|
+
@temp_dir = Dir.mktmpdir('event_system_test')
|
|
31
|
+
end
|
|
32
|
+
end
|
|
33
|
+
|
|
34
|
+
# Helper methods for testing
|
|
35
|
+
module EventSystemTestHelpers
|
|
36
|
+
def create_test_event(type = :test_event, source = 'TestSource', data = {})
|
|
37
|
+
EventSystem::Event.new(type, source, data)
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
def create_test_manager(storage_type = :memory, options = {})
|
|
41
|
+
config = {
|
|
42
|
+
storage_type: storage_type,
|
|
43
|
+
storage_options: options
|
|
44
|
+
}
|
|
45
|
+
EventSystem.create_manager(config)
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
def create_file_manager(temp_dir = nil)
|
|
49
|
+
temp_dir ||= @temp_dir
|
|
50
|
+
create_test_manager(:file, { directory: temp_dir })
|
|
51
|
+
end
|
|
52
|
+
|
|
53
|
+
def create_test_subscriber(name = 'TestSubscriber')
|
|
54
|
+
Class.new do
|
|
55
|
+
include EventSystem::EventSubscriber
|
|
56
|
+
attr_reader :name, :events_received
|
|
57
|
+
|
|
58
|
+
def initialize(name)
|
|
59
|
+
@name = name
|
|
60
|
+
@events_received = []
|
|
61
|
+
end
|
|
62
|
+
|
|
63
|
+
def handle_event(event)
|
|
64
|
+
@events_received << event
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def handles_event_type?(event_type)
|
|
68
|
+
true
|
|
69
|
+
end
|
|
70
|
+
|
|
71
|
+
def event_priority
|
|
72
|
+
0
|
|
73
|
+
end
|
|
74
|
+
end.new(name)
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
|
|
78
|
+
RSpec.configure do |config|
|
|
79
|
+
config.include EventSystemTestHelpers
|
|
80
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: event_system
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.1.0
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- David Silva
|
|
8
|
+
bindir: exe
|
|
9
|
+
cert_chain: []
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
11
|
+
dependencies:
|
|
12
|
+
- !ruby/object:Gem::Dependency
|
|
13
|
+
name: json
|
|
14
|
+
requirement: !ruby/object:Gem::Requirement
|
|
15
|
+
requirements:
|
|
16
|
+
- - "~>"
|
|
17
|
+
- !ruby/object:Gem::Version
|
|
18
|
+
version: '2.0'
|
|
19
|
+
type: :runtime
|
|
20
|
+
prerelease: false
|
|
21
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
22
|
+
requirements:
|
|
23
|
+
- - "~>"
|
|
24
|
+
- !ruby/object:Gem::Version
|
|
25
|
+
version: '2.0'
|
|
26
|
+
- !ruby/object:Gem::Dependency
|
|
27
|
+
name: rspec
|
|
28
|
+
requirement: !ruby/object:Gem::Requirement
|
|
29
|
+
requirements:
|
|
30
|
+
- - "~>"
|
|
31
|
+
- !ruby/object:Gem::Version
|
|
32
|
+
version: '3.0'
|
|
33
|
+
type: :development
|
|
34
|
+
prerelease: false
|
|
35
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
36
|
+
requirements:
|
|
37
|
+
- - "~>"
|
|
38
|
+
- !ruby/object:Gem::Version
|
|
39
|
+
version: '3.0'
|
|
40
|
+
- !ruby/object:Gem::Dependency
|
|
41
|
+
name: rubocop
|
|
42
|
+
requirement: !ruby/object:Gem::Requirement
|
|
43
|
+
requirements:
|
|
44
|
+
- - "~>"
|
|
45
|
+
- !ruby/object:Gem::Version
|
|
46
|
+
version: '1.0'
|
|
47
|
+
type: :development
|
|
48
|
+
prerelease: false
|
|
49
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
50
|
+
requirements:
|
|
51
|
+
- - "~>"
|
|
52
|
+
- !ruby/object:Gem::Version
|
|
53
|
+
version: '1.0'
|
|
54
|
+
- !ruby/object:Gem::Dependency
|
|
55
|
+
name: yard
|
|
56
|
+
requirement: !ruby/object:Gem::Requirement
|
|
57
|
+
requirements:
|
|
58
|
+
- - "~>"
|
|
59
|
+
- !ruby/object:Gem::Version
|
|
60
|
+
version: '0.9'
|
|
61
|
+
type: :development
|
|
62
|
+
prerelease: false
|
|
63
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
64
|
+
requirements:
|
|
65
|
+
- - "~>"
|
|
66
|
+
- !ruby/object:Gem::Version
|
|
67
|
+
version: '0.9'
|
|
68
|
+
- !ruby/object:Gem::Dependency
|
|
69
|
+
name: simplecov
|
|
70
|
+
requirement: !ruby/object:Gem::Requirement
|
|
71
|
+
requirements:
|
|
72
|
+
- - "~>"
|
|
73
|
+
- !ruby/object:Gem::Version
|
|
74
|
+
version: '0.21'
|
|
75
|
+
type: :development
|
|
76
|
+
prerelease: false
|
|
77
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
78
|
+
requirements:
|
|
79
|
+
- - "~>"
|
|
80
|
+
- !ruby/object:Gem::Version
|
|
81
|
+
version: '0.21'
|
|
82
|
+
- !ruby/object:Gem::Dependency
|
|
83
|
+
name: redis
|
|
84
|
+
requirement: !ruby/object:Gem::Requirement
|
|
85
|
+
requirements:
|
|
86
|
+
- - "~>"
|
|
87
|
+
- !ruby/object:Gem::Version
|
|
88
|
+
version: '4.0'
|
|
89
|
+
type: :development
|
|
90
|
+
prerelease: false
|
|
91
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
92
|
+
requirements:
|
|
93
|
+
- - "~>"
|
|
94
|
+
- !ruby/object:Gem::Version
|
|
95
|
+
version: '4.0'
|
|
96
|
+
- !ruby/object:Gem::Dependency
|
|
97
|
+
name: pg
|
|
98
|
+
requirement: !ruby/object:Gem::Requirement
|
|
99
|
+
requirements:
|
|
100
|
+
- - "~>"
|
|
101
|
+
- !ruby/object:Gem::Version
|
|
102
|
+
version: '1.0'
|
|
103
|
+
type: :development
|
|
104
|
+
prerelease: false
|
|
105
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
106
|
+
requirements:
|
|
107
|
+
- - "~>"
|
|
108
|
+
- !ruby/object:Gem::Version
|
|
109
|
+
version: '1.0'
|
|
110
|
+
description: Event-driven architecture with pluggable storage backends, visualization
|
|
111
|
+
tools, and comprehensive logging. Perfect for building decoupled, maintainable applications.
|
|
112
|
+
email:
|
|
113
|
+
- davidslv@users.noreply.github.com
|
|
114
|
+
executables:
|
|
115
|
+
- event_system
|
|
116
|
+
extensions: []
|
|
117
|
+
extra_rdoc_files: []
|
|
118
|
+
files:
|
|
119
|
+
- ".rspec"
|
|
120
|
+
- README.md
|
|
121
|
+
- Rakefile
|
|
122
|
+
- docs/event_visualizations/example_timeline.html
|
|
123
|
+
- docs/example_logs/events_20251027_151744.jsonl
|
|
124
|
+
- docs/example_logs/events_20251027_151802.jsonl
|
|
125
|
+
- docs/examples/basic_usage.rb
|
|
126
|
+
- exe/event_system
|
|
127
|
+
- lib/event_system.rb
|
|
128
|
+
- lib/event_system/configuration.rb
|
|
129
|
+
- lib/event_system/event.rb
|
|
130
|
+
- lib/event_system/event_manager.rb
|
|
131
|
+
- lib/event_system/event_subscriber.rb
|
|
132
|
+
- lib/event_system/storage/base.rb
|
|
133
|
+
- lib/event_system/storage/file_store.rb
|
|
134
|
+
- lib/event_system/storage/memory_store.rb
|
|
135
|
+
- lib/event_system/version.rb
|
|
136
|
+
- lib/event_system/visualization/timeline_generator.rb
|
|
137
|
+
- spec/event_system/configuration_spec.rb
|
|
138
|
+
- spec/event_system/event_manager_spec.rb
|
|
139
|
+
- spec/event_system/event_spec.rb
|
|
140
|
+
- spec/event_system/event_subscriber_spec.rb
|
|
141
|
+
- spec/event_system/storage/file_store_spec.rb
|
|
142
|
+
- spec/event_system/storage/memory_store_spec.rb
|
|
143
|
+
- spec/event_system/visualization/timeline_generator_spec.rb
|
|
144
|
+
- spec/event_system_spec.rb
|
|
145
|
+
- spec/integration/readme_examples_spec.rb
|
|
146
|
+
- spec/spec_helper.rb
|
|
147
|
+
homepage: https://github.com/davidslv/event_system
|
|
148
|
+
licenses:
|
|
149
|
+
- MIT
|
|
150
|
+
metadata:
|
|
151
|
+
allowed_push_host: https://rubygems.org
|
|
152
|
+
homepage_uri: https://github.com/davidslv/event_system
|
|
153
|
+
source_code_uri: https://github.com/davidslv/event_system
|
|
154
|
+
rdoc_options: []
|
|
155
|
+
require_paths:
|
|
156
|
+
- lib
|
|
157
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
158
|
+
requirements:
|
|
159
|
+
- - ">="
|
|
160
|
+
- !ruby/object:Gem::Version
|
|
161
|
+
version: 2.7.0
|
|
162
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
163
|
+
requirements:
|
|
164
|
+
- - ">="
|
|
165
|
+
- !ruby/object:Gem::Version
|
|
166
|
+
version: '0'
|
|
167
|
+
requirements: []
|
|
168
|
+
rubygems_version: 3.6.9
|
|
169
|
+
specification_version: 4
|
|
170
|
+
summary: A flexible, agnostic event system for Ruby applications
|
|
171
|
+
test_files: []
|