nestlens 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.
- package/LICENSE +21 -0
- package/README.md +145 -0
- package/dist/__tests__/api/api.controller.spec.d.ts +2 -0
- package/dist/__tests__/api/api.controller.spec.d.ts.map +1 -0
- package/dist/__tests__/api/api.controller.spec.js +982 -0
- package/dist/__tests__/api/api.controller.spec.js.map +1 -0
- package/dist/__tests__/api/api.guard.spec.d.ts +2 -0
- package/dist/__tests__/api/api.guard.spec.d.ts.map +1 -0
- package/dist/__tests__/api/api.guard.spec.js +572 -0
- package/dist/__tests__/api/api.guard.spec.js.map +1 -0
- package/dist/__tests__/api/dashboard.controller.spec.d.ts +2 -0
- package/dist/__tests__/api/dashboard.controller.spec.d.ts.map +1 -0
- package/dist/__tests__/api/dashboard.controller.spec.js +474 -0
- package/dist/__tests__/api/dashboard.controller.spec.js.map +1 -0
- package/dist/__tests__/api/tag.controller.spec.d.ts +2 -0
- package/dist/__tests__/api/tag.controller.spec.d.ts.map +1 -0
- package/dist/__tests__/api/tag.controller.spec.js +280 -0
- package/dist/__tests__/api/tag.controller.spec.js.map +1 -0
- package/dist/__tests__/collector.service.spec.d.ts +2 -0
- package/dist/__tests__/collector.service.spec.d.ts.map +1 -0
- package/dist/__tests__/collector.service.spec.js +240 -0
- package/dist/__tests__/collector.service.spec.js.map +1 -0
- package/dist/__tests__/core/collector.service.spec.d.ts +2 -0
- package/dist/__tests__/core/collector.service.spec.d.ts.map +1 -0
- package/dist/__tests__/core/collector.service.spec.js +526 -0
- package/dist/__tests__/core/collector.service.spec.js.map +1 -0
- package/dist/__tests__/core/family-hash.service.spec.d.ts +2 -0
- package/dist/__tests__/core/family-hash.service.spec.d.ts.map +1 -0
- package/dist/__tests__/core/family-hash.service.spec.js +1117 -0
- package/dist/__tests__/core/family-hash.service.spec.js.map +1 -0
- package/dist/__tests__/core/pruning.service.spec.d.ts +2 -0
- package/dist/__tests__/core/pruning.service.spec.d.ts.map +1 -0
- package/dist/__tests__/core/pruning.service.spec.js +224 -0
- package/dist/__tests__/core/pruning.service.spec.js.map +1 -0
- package/dist/__tests__/core/storage/sqlite.storage.spec.d.ts +2 -0
- package/dist/__tests__/core/storage/sqlite.storage.spec.d.ts.map +1 -0
- package/dist/__tests__/core/storage/sqlite.storage.spec.js +853 -0
- package/dist/__tests__/core/storage/sqlite.storage.spec.js.map +1 -0
- package/dist/__tests__/core/tag.service.spec.d.ts +2 -0
- package/dist/__tests__/core/tag.service.spec.d.ts.map +1 -0
- package/dist/__tests__/core/tag.service.spec.js +994 -0
- package/dist/__tests__/core/tag.service.spec.js.map +1 -0
- package/dist/__tests__/family-hash.service.spec.d.ts +2 -0
- package/dist/__tests__/family-hash.service.spec.d.ts.map +1 -0
- package/dist/__tests__/family-hash.service.spec.js +325 -0
- package/dist/__tests__/family-hash.service.spec.js.map +1 -0
- package/dist/__tests__/filters/api-filters.spec.d.ts +2 -0
- package/dist/__tests__/filters/api-filters.spec.d.ts.map +1 -0
- package/dist/__tests__/filters/api-filters.spec.js +172 -0
- package/dist/__tests__/filters/api-filters.spec.js.map +1 -0
- package/dist/__tests__/filters/entry-factories.d.ts +20 -0
- package/dist/__tests__/filters/entry-factories.d.ts.map +1 -0
- package/dist/__tests__/filters/entry-factories.js +288 -0
- package/dist/__tests__/filters/entry-factories.js.map +1 -0
- package/dist/__tests__/filters/filter-contract.spec.d.ts +2 -0
- package/dist/__tests__/filters/filter-contract.spec.d.ts.map +1 -0
- package/dist/__tests__/filters/filter-contract.spec.js +230 -0
- package/dist/__tests__/filters/filter-contract.spec.js.map +1 -0
- package/dist/__tests__/filters/filter-test-data.d.ts +26 -0
- package/dist/__tests__/filters/filter-test-data.d.ts.map +1 -0
- package/dist/__tests__/filters/filter-test-data.js +374 -0
- package/dist/__tests__/filters/filter-test-data.js.map +1 -0
- package/dist/__tests__/filters/storage-filters.spec.d.ts +2 -0
- package/dist/__tests__/filters/storage-filters.spec.d.ts.map +1 -0
- package/dist/__tests__/filters/storage-filters.spec.js +699 -0
- package/dist/__tests__/filters/storage-filters.spec.js.map +1 -0
- package/dist/__tests__/filters/test-utils.d.ts +23 -0
- package/dist/__tests__/filters/test-utils.d.ts.map +1 -0
- package/dist/__tests__/filters/test-utils.js +54 -0
- package/dist/__tests__/filters/test-utils.js.map +1 -0
- package/dist/__tests__/nestlens.module.spec.d.ts +2 -0
- package/dist/__tests__/nestlens.module.spec.d.ts.map +1 -0
- package/dist/__tests__/nestlens.module.spec.js +620 -0
- package/dist/__tests__/nestlens.module.spec.js.map +1 -0
- package/dist/__tests__/pruning.service.spec.d.ts +2 -0
- package/dist/__tests__/pruning.service.spec.d.ts.map +1 -0
- package/dist/__tests__/pruning.service.spec.js +142 -0
- package/dist/__tests__/pruning.service.spec.js.map +1 -0
- package/dist/__tests__/setup.d.ts +7 -0
- package/dist/__tests__/setup.d.ts.map +1 -0
- package/dist/__tests__/setup.js +24 -0
- package/dist/__tests__/setup.js.map +1 -0
- package/dist/__tests__/tag.service.spec.d.ts +2 -0
- package/dist/__tests__/tag.service.spec.d.ts.map +1 -0
- package/dist/__tests__/tag.service.spec.js +482 -0
- package/dist/__tests__/tag.service.spec.js.map +1 -0
- package/dist/__tests__/watchers/batch.watcher.spec.d.ts +2 -0
- package/dist/__tests__/watchers/batch.watcher.spec.d.ts.map +1 -0
- package/dist/__tests__/watchers/batch.watcher.spec.js +515 -0
- package/dist/__tests__/watchers/batch.watcher.spec.js.map +1 -0
- package/dist/__tests__/watchers/cache.watcher.spec.d.ts +2 -0
- package/dist/__tests__/watchers/cache.watcher.spec.d.ts.map +1 -0
- package/dist/__tests__/watchers/cache.watcher.spec.js +395 -0
- package/dist/__tests__/watchers/cache.watcher.spec.js.map +1 -0
- package/dist/__tests__/watchers/command.watcher.spec.d.ts +2 -0
- package/dist/__tests__/watchers/command.watcher.spec.d.ts.map +1 -0
- package/dist/__tests__/watchers/command.watcher.spec.js +598 -0
- package/dist/__tests__/watchers/command.watcher.spec.js.map +1 -0
- package/dist/__tests__/watchers/dump.watcher.spec.d.ts +2 -0
- package/dist/__tests__/watchers/dump.watcher.spec.d.ts.map +1 -0
- package/dist/__tests__/watchers/dump.watcher.spec.js +724 -0
- package/dist/__tests__/watchers/dump.watcher.spec.js.map +1 -0
- package/dist/__tests__/watchers/event.watcher.spec.d.ts +2 -0
- package/dist/__tests__/watchers/event.watcher.spec.d.ts.map +1 -0
- package/dist/__tests__/watchers/event.watcher.spec.js +316 -0
- package/dist/__tests__/watchers/event.watcher.spec.js.map +1 -0
- package/dist/__tests__/watchers/exception.watcher.spec.d.ts +2 -0
- package/dist/__tests__/watchers/exception.watcher.spec.d.ts.map +1 -0
- package/dist/__tests__/watchers/exception.watcher.spec.js +495 -0
- package/dist/__tests__/watchers/exception.watcher.spec.js.map +1 -0
- package/dist/__tests__/watchers/gate.watcher.spec.d.ts +2 -0
- package/dist/__tests__/watchers/gate.watcher.spec.d.ts.map +1 -0
- package/dist/__tests__/watchers/gate.watcher.spec.js +683 -0
- package/dist/__tests__/watchers/gate.watcher.spec.js.map +1 -0
- package/dist/__tests__/watchers/http-client.watcher.spec.d.ts +2 -0
- package/dist/__tests__/watchers/http-client.watcher.spec.d.ts.map +1 -0
- package/dist/__tests__/watchers/http-client.watcher.spec.js +888 -0
- package/dist/__tests__/watchers/http-client.watcher.spec.js.map +1 -0
- package/dist/__tests__/watchers/job.watcher.spec.d.ts +2 -0
- package/dist/__tests__/watchers/job.watcher.spec.d.ts.map +1 -0
- package/dist/__tests__/watchers/job.watcher.spec.js +513 -0
- package/dist/__tests__/watchers/job.watcher.spec.js.map +1 -0
- package/dist/__tests__/watchers/log.watcher.spec.d.ts +2 -0
- package/dist/__tests__/watchers/log.watcher.spec.d.ts.map +1 -0
- package/dist/__tests__/watchers/log.watcher.spec.js +428 -0
- package/dist/__tests__/watchers/log.watcher.spec.js.map +1 -0
- package/dist/__tests__/watchers/mail.watcher.spec.d.ts +2 -0
- package/dist/__tests__/watchers/mail.watcher.spec.d.ts.map +1 -0
- package/dist/__tests__/watchers/mail.watcher.spec.js +425 -0
- package/dist/__tests__/watchers/mail.watcher.spec.js.map +1 -0
- package/dist/__tests__/watchers/model.watcher.spec.d.ts +2 -0
- package/dist/__tests__/watchers/model.watcher.spec.d.ts.map +1 -0
- package/dist/__tests__/watchers/model.watcher.spec.js +675 -0
- package/dist/__tests__/watchers/model.watcher.spec.js.map +1 -0
- package/dist/__tests__/watchers/notification.watcher.spec.d.ts +2 -0
- package/dist/__tests__/watchers/notification.watcher.spec.d.ts.map +1 -0
- package/dist/__tests__/watchers/notification.watcher.spec.js +595 -0
- package/dist/__tests__/watchers/notification.watcher.spec.js.map +1 -0
- package/dist/__tests__/watchers/query/types.spec.d.ts +2 -0
- package/dist/__tests__/watchers/query/types.spec.d.ts.map +1 -0
- package/dist/__tests__/watchers/query/types.spec.js +292 -0
- package/dist/__tests__/watchers/query/types.spec.js.map +1 -0
- package/dist/__tests__/watchers/query.watcher.spec.d.ts +2 -0
- package/dist/__tests__/watchers/query.watcher.spec.d.ts.map +1 -0
- package/dist/__tests__/watchers/query.watcher.spec.js +597 -0
- package/dist/__tests__/watchers/query.watcher.spec.js.map +1 -0
- package/dist/__tests__/watchers/redis.watcher.spec.d.ts +2 -0
- package/dist/__tests__/watchers/redis.watcher.spec.d.ts.map +1 -0
- package/dist/__tests__/watchers/redis.watcher.spec.js +634 -0
- package/dist/__tests__/watchers/redis.watcher.spec.js.map +1 -0
- package/dist/__tests__/watchers/request.watcher.spec.d.ts +2 -0
- package/dist/__tests__/watchers/request.watcher.spec.d.ts.map +1 -0
- package/dist/__tests__/watchers/request.watcher.spec.js +1017 -0
- package/dist/__tests__/watchers/request.watcher.spec.js.map +1 -0
- package/dist/__tests__/watchers/schedule.watcher.spec.d.ts +2 -0
- package/dist/__tests__/watchers/schedule.watcher.spec.d.ts.map +1 -0
- package/dist/__tests__/watchers/schedule.watcher.spec.js +338 -0
- package/dist/__tests__/watchers/schedule.watcher.spec.js.map +1 -0
- package/dist/__tests__/watchers/view.watcher.spec.d.ts +2 -0
- package/dist/__tests__/watchers/view.watcher.spec.d.ts.map +1 -0
- package/dist/__tests__/watchers/view.watcher.spec.js +564 -0
- package/dist/__tests__/watchers/view.watcher.spec.js.map +1 -0
- package/dist/api/api.controller.d.ts +193 -0
- package/dist/api/api.controller.d.ts.map +1 -0
- package/dist/api/api.controller.js +562 -0
- package/dist/api/api.controller.js.map +1 -0
- package/dist/api/api.guard.d.ts +77 -0
- package/dist/api/api.guard.d.ts.map +1 -0
- package/dist/api/api.guard.js +294 -0
- package/dist/api/api.guard.js.map +1 -0
- package/dist/api/dashboard.controller.d.ts +49 -0
- package/dist/api/dashboard.controller.d.ts.map +1 -0
- package/dist/api/dashboard.controller.js +472 -0
- package/dist/api/dashboard.controller.js.map +1 -0
- package/dist/api/index.d.ts +5 -0
- package/dist/api/index.d.ts.map +1 -0
- package/dist/api/index.js +21 -0
- package/dist/api/index.js.map +1 -0
- package/dist/api/tag.controller.d.ts +65 -0
- package/dist/api/tag.controller.d.ts.map +1 -0
- package/dist/api/tag.controller.js +149 -0
- package/dist/api/tag.controller.js.map +1 -0
- package/dist/core/collector.service.d.ts +80 -0
- package/dist/core/collector.service.d.ts.map +1 -0
- package/dist/core/collector.service.js +255 -0
- package/dist/core/collector.service.js.map +1 -0
- package/dist/core/family-hash.service.d.ts +64 -0
- package/dist/core/family-hash.service.d.ts.map +1 -0
- package/dist/core/family-hash.service.js +281 -0
- package/dist/core/family-hash.service.js.map +1 -0
- package/dist/core/index.d.ts +4 -0
- package/dist/core/index.d.ts.map +1 -0
- package/dist/core/index.js +20 -0
- package/dist/core/index.js.map +1 -0
- package/dist/core/pruning.service.d.ts +16 -0
- package/dist/core/pruning.service.d.ts.map +1 -0
- package/dist/core/pruning.service.js +71 -0
- package/dist/core/pruning.service.js.map +1 -0
- package/dist/core/storage/index.d.ts +3 -0
- package/dist/core/storage/index.d.ts.map +1 -0
- package/dist/core/storage/index.js +19 -0
- package/dist/core/storage/index.js.map +1 -0
- package/dist/core/storage/sqlite.storage.d.ts +60 -0
- package/dist/core/storage/sqlite.storage.d.ts.map +1 -0
- package/dist/core/storage/sqlite.storage.js +929 -0
- package/dist/core/storage/sqlite.storage.js.map +1 -0
- package/dist/core/storage/storage.interface.d.ts +122 -0
- package/dist/core/storage/storage.interface.d.ts.map +1 -0
- package/dist/core/storage/storage.interface.js +5 -0
- package/dist/core/storage/storage.interface.js.map +1 -0
- package/dist/core/tag.service.d.ts +71 -0
- package/dist/core/tag.service.d.ts.map +1 -0
- package/dist/core/tag.service.js +568 -0
- package/dist/core/tag.service.js.map +1 -0
- package/dist/dashboard/public/assets/BatchesPage-DFT4fKlJ.js +1 -0
- package/dist/dashboard/public/assets/CachePage-CRy1Tjb8.js +1 -0
- package/dist/dashboard/public/assets/ClickableBadge-CV5J3THx.js +1 -0
- package/dist/dashboard/public/assets/CommandsPage-DdRnTm-W.js +1 -0
- package/dist/dashboard/public/assets/DashboardPage-CjaRZXYy.js +26 -0
- package/dist/dashboard/public/assets/DataTable-B6o9H8lh.js +88 -0
- package/dist/dashboard/public/assets/DumpsPage-DO8y1RTg.js +1 -0
- package/dist/dashboard/public/assets/EntryDetailPage-By-YcAGL.js +125 -0
- package/dist/dashboard/public/assets/EventsPage-u-r4AiT4.js +1 -0
- package/dist/dashboard/public/assets/ExceptionsPage-DXUcARr1.js +6 -0
- package/dist/dashboard/public/assets/GatesPage-DpeP7CDZ.js +1 -0
- package/dist/dashboard/public/assets/HttpClientPage-BJ4-5E6t.js +1 -0
- package/dist/dashboard/public/assets/JobsPage-Dv3KaX2x.js +1 -0
- package/dist/dashboard/public/assets/LogsPage-D0Q3yDb1.js +1 -0
- package/dist/dashboard/public/assets/MailPage-Bf8C6WF6.js +1 -0
- package/dist/dashboard/public/assets/ModelsPage-BMHncI5y.js +1 -0
- package/dist/dashboard/public/assets/NotificationsPage-D5-I-Oxb.js +1 -0
- package/dist/dashboard/public/assets/QueriesPage-oNp0i6Gt.js +1 -0
- package/dist/dashboard/public/assets/RedisPage-_GeS2OD8.js +1 -0
- package/dist/dashboard/public/assets/RequestsPage-BCwqu9US.js +1 -0
- package/dist/dashboard/public/assets/SchedulePage-CR0P-oX6.js +1 -0
- package/dist/dashboard/public/assets/ViewsPage-Dsy5ECRA.js +1 -0
- package/dist/dashboard/public/assets/calendar-DfK3x-6B.js +6 -0
- package/dist/dashboard/public/assets/circle-check-big-DcsYW8y8.js +6 -0
- package/dist/dashboard/public/assets/format-BFldcnCk.js +1 -0
- package/dist/dashboard/public/assets/index-DmeA1maE.css +1 -0
- package/dist/dashboard/public/assets/index-rkbGYdU7.js +351 -0
- package/dist/dashboard/public/assets/types-Cldoe2db.js +1 -0
- package/dist/dashboard/public/assets/vendor-B2nVRih0.js +43 -0
- package/dist/dashboard/public/assets/zap-DqtRi0JM.js +6 -0
- package/dist/dashboard/public/index.html +15 -0
- package/dist/dashboard/public/nestlens-icon.svg +9 -0
- package/dist/index.d.ts +22 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +69 -0
- package/dist/index.js.map +1 -0
- package/dist/nestlens.config.d.ts +216 -0
- package/dist/nestlens.config.d.ts.map +1 -0
- package/dist/nestlens.config.js +57 -0
- package/dist/nestlens.config.js.map +1 -0
- package/dist/nestlens.module.d.ts +10 -0
- package/dist/nestlens.module.d.ts.map +1 -0
- package/dist/nestlens.module.js +211 -0
- package/dist/nestlens.module.js.map +1 -0
- package/dist/types/entry.types.d.ts +368 -0
- package/dist/types/entry.types.d.ts.map +1 -0
- package/dist/types/entry.types.js +3 -0
- package/dist/types/entry.types.js.map +1 -0
- package/dist/types/index.d.ts +4 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +20 -0
- package/dist/types/index.js.map +1 -0
- package/dist/types/request.types.d.ts +9 -0
- package/dist/types/request.types.d.ts.map +1 -0
- package/dist/types/request.types.js +3 -0
- package/dist/types/request.types.js.map +1 -0
- package/dist/types/tag.types.d.ts +32 -0
- package/dist/types/tag.types.d.ts.map +1 -0
- package/dist/types/tag.types.js +3 -0
- package/dist/types/tag.types.js.map +1 -0
- package/dist/watchers/batch.watcher.d.ts +48 -0
- package/dist/watchers/batch.watcher.d.ts.map +1 -0
- package/dist/watchers/batch.watcher.js +185 -0
- package/dist/watchers/batch.watcher.js.map +1 -0
- package/dist/watchers/cache.watcher.d.ts +19 -0
- package/dist/watchers/cache.watcher.d.ts.map +1 -0
- package/dist/watchers/cache.watcher.js +158 -0
- package/dist/watchers/cache.watcher.js.map +1 -0
- package/dist/watchers/command.watcher.d.ts +32 -0
- package/dist/watchers/command.watcher.d.ts.map +1 -0
- package/dist/watchers/command.watcher.js +174 -0
- package/dist/watchers/command.watcher.js.map +1 -0
- package/dist/watchers/dump.watcher.d.ts +52 -0
- package/dist/watchers/dump.watcher.d.ts.map +1 -0
- package/dist/watchers/dump.watcher.js +234 -0
- package/dist/watchers/dump.watcher.js.map +1 -0
- package/dist/watchers/event.watcher.d.ts +20 -0
- package/dist/watchers/event.watcher.d.ts.map +1 -0
- package/dist/watchers/event.watcher.js +123 -0
- package/dist/watchers/event.watcher.js.map +1 -0
- package/dist/watchers/exception.watcher.d.ts +15 -0
- package/dist/watchers/exception.watcher.d.ts.map +1 -0
- package/dist/watchers/exception.watcher.js +117 -0
- package/dist/watchers/exception.watcher.js.map +1 -0
- package/dist/watchers/gate.watcher.d.ts +40 -0
- package/dist/watchers/gate.watcher.d.ts.map +1 -0
- package/dist/watchers/gate.watcher.js +200 -0
- package/dist/watchers/gate.watcher.js.map +1 -0
- package/dist/watchers/http-client.watcher.d.ts +34 -0
- package/dist/watchers/http-client.watcher.d.ts.map +1 -0
- package/dist/watchers/http-client.watcher.js +259 -0
- package/dist/watchers/http-client.watcher.js.map +1 -0
- package/dist/watchers/index.d.ts +19 -0
- package/dist/watchers/index.d.ts.map +1 -0
- package/dist/watchers/index.js +35 -0
- package/dist/watchers/index.js.map +1 -0
- package/dist/watchers/job.watcher.d.ts +27 -0
- package/dist/watchers/job.watcher.d.ts.map +1 -0
- package/dist/watchers/job.watcher.js +190 -0
- package/dist/watchers/job.watcher.js.map +1 -0
- package/dist/watchers/log.watcher.d.ts +26 -0
- package/dist/watchers/log.watcher.d.ts.map +1 -0
- package/dist/watchers/log.watcher.js +122 -0
- package/dist/watchers/log.watcher.js.map +1 -0
- package/dist/watchers/mail.watcher.d.ts +26 -0
- package/dist/watchers/mail.watcher.d.ts.map +1 -0
- package/dist/watchers/mail.watcher.js +154 -0
- package/dist/watchers/mail.watcher.js.map +1 -0
- package/dist/watchers/model.watcher.d.ts +54 -0
- package/dist/watchers/model.watcher.d.ts.map +1 -0
- package/dist/watchers/model.watcher.js +343 -0
- package/dist/watchers/model.watcher.js.map +1 -0
- package/dist/watchers/notification.watcher.d.ts +48 -0
- package/dist/watchers/notification.watcher.d.ts.map +1 -0
- package/dist/watchers/notification.watcher.js +215 -0
- package/dist/watchers/notification.watcher.js.map +1 -0
- package/dist/watchers/query/index.d.ts +3 -0
- package/dist/watchers/query/index.d.ts.map +1 -0
- package/dist/watchers/query/index.js +19 -0
- package/dist/watchers/query/index.js.map +1 -0
- package/dist/watchers/query/query.watcher.d.ts +27 -0
- package/dist/watchers/query/query.watcher.d.ts.map +1 -0
- package/dist/watchers/query/query.watcher.js +167 -0
- package/dist/watchers/query/query.watcher.js.map +1 -0
- package/dist/watchers/query/types.d.ts +60 -0
- package/dist/watchers/query/types.d.ts.map +1 -0
- package/dist/watchers/query/types.js +55 -0
- package/dist/watchers/query/types.js.map +1 -0
- package/dist/watchers/redis.watcher.d.ts +43 -0
- package/dist/watchers/redis.watcher.d.ts.map +1 -0
- package/dist/watchers/redis.watcher.js +225 -0
- package/dist/watchers/redis.watcher.js.map +1 -0
- package/dist/watchers/request.watcher.d.ts +21 -0
- package/dist/watchers/request.watcher.d.ts.map +1 -0
- package/dist/watchers/request.watcher.js +287 -0
- package/dist/watchers/request.watcher.js.map +1 -0
- package/dist/watchers/schedule.watcher.d.ts +25 -0
- package/dist/watchers/schedule.watcher.d.ts.map +1 -0
- package/dist/watchers/schedule.watcher.js +168 -0
- package/dist/watchers/schedule.watcher.js.map +1 -0
- package/dist/watchers/view.watcher.d.ts +51 -0
- package/dist/watchers/view.watcher.d.ts.map +1 -0
- package/dist/watchers/view.watcher.js +219 -0
- package/dist/watchers/view.watcher.js.map +1 -0
- package/package.json +86 -0
|
@@ -0,0 +1,1117 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
const family_hash_service_1 = require("../../core/family-hash.service");
|
|
4
|
+
describe('FamilyHashService', () => {
|
|
5
|
+
let service;
|
|
6
|
+
beforeEach(() => {
|
|
7
|
+
service = new family_hash_service_1.FamilyHashService();
|
|
8
|
+
});
|
|
9
|
+
describe('generateFamilyHash', () => {
|
|
10
|
+
describe('Exception Entries', () => {
|
|
11
|
+
it('should generate hash for exception with stack trace', () => {
|
|
12
|
+
// Arrange
|
|
13
|
+
const entry = {
|
|
14
|
+
id: 1,
|
|
15
|
+
type: 'exception',
|
|
16
|
+
timestamp: new Date().toISOString(),
|
|
17
|
+
payload: {
|
|
18
|
+
name: 'TypeError',
|
|
19
|
+
message: 'Cannot read property "id" of undefined',
|
|
20
|
+
stack: 'TypeError: Cannot read property "id" of undefined\n at UserService.getUser (/src/services/user.service.ts:42:15)',
|
|
21
|
+
},
|
|
22
|
+
};
|
|
23
|
+
// Act
|
|
24
|
+
const hash = service.generateFamilyHash(entry);
|
|
25
|
+
// Assert
|
|
26
|
+
expect(hash).toBeDefined();
|
|
27
|
+
expect(hash).toHaveLength(16);
|
|
28
|
+
});
|
|
29
|
+
it('should generate same hash for similar exceptions', () => {
|
|
30
|
+
// Arrange
|
|
31
|
+
const entry1 = {
|
|
32
|
+
id: 1,
|
|
33
|
+
type: 'exception',
|
|
34
|
+
timestamp: new Date().toISOString(),
|
|
35
|
+
payload: {
|
|
36
|
+
name: 'TypeError',
|
|
37
|
+
message: 'Cannot read property "id" of undefined',
|
|
38
|
+
stack: 'at UserService.getUser (/src/services/user.service.ts:42:15)',
|
|
39
|
+
},
|
|
40
|
+
};
|
|
41
|
+
const entry2 = {
|
|
42
|
+
id: 2,
|
|
43
|
+
type: 'exception',
|
|
44
|
+
timestamp: new Date().toISOString(),
|
|
45
|
+
payload: {
|
|
46
|
+
name: 'TypeError',
|
|
47
|
+
message: 'Cannot read property "id" of undefined',
|
|
48
|
+
stack: 'at UserService.getUser (/src/services/user.service.ts:42:15)',
|
|
49
|
+
},
|
|
50
|
+
};
|
|
51
|
+
// Act
|
|
52
|
+
const hash1 = service.generateFamilyHash(entry1);
|
|
53
|
+
const hash2 = service.generateFamilyHash(entry2);
|
|
54
|
+
// Assert
|
|
55
|
+
expect(hash1).toBe(hash2);
|
|
56
|
+
});
|
|
57
|
+
it('should generate different hash for different exception types', () => {
|
|
58
|
+
// Arrange
|
|
59
|
+
const entry1 = {
|
|
60
|
+
id: 1,
|
|
61
|
+
type: 'exception',
|
|
62
|
+
timestamp: new Date().toISOString(),
|
|
63
|
+
payload: {
|
|
64
|
+
name: 'TypeError',
|
|
65
|
+
message: 'Error message',
|
|
66
|
+
stack: 'at file.ts:10:5',
|
|
67
|
+
},
|
|
68
|
+
};
|
|
69
|
+
const entry2 = {
|
|
70
|
+
id: 2,
|
|
71
|
+
type: 'exception',
|
|
72
|
+
timestamp: new Date().toISOString(),
|
|
73
|
+
payload: {
|
|
74
|
+
name: 'RangeError',
|
|
75
|
+
message: 'Error message',
|
|
76
|
+
stack: 'at file.ts:10:5',
|
|
77
|
+
},
|
|
78
|
+
};
|
|
79
|
+
// Act
|
|
80
|
+
const hash1 = service.generateFamilyHash(entry1);
|
|
81
|
+
const hash2 = service.generateFamilyHash(entry2);
|
|
82
|
+
// Assert
|
|
83
|
+
expect(hash1).not.toBe(hash2);
|
|
84
|
+
});
|
|
85
|
+
it('should normalize error messages with UUIDs', () => {
|
|
86
|
+
// Arrange
|
|
87
|
+
const entry1 = {
|
|
88
|
+
id: 1,
|
|
89
|
+
type: 'exception',
|
|
90
|
+
timestamp: new Date().toISOString(),
|
|
91
|
+
payload: {
|
|
92
|
+
name: 'NotFoundError',
|
|
93
|
+
message: 'User 123e4567-e89b-12d3-a456-426614174000 not found',
|
|
94
|
+
},
|
|
95
|
+
};
|
|
96
|
+
const entry2 = {
|
|
97
|
+
id: 2,
|
|
98
|
+
type: 'exception',
|
|
99
|
+
timestamp: new Date().toISOString(),
|
|
100
|
+
payload: {
|
|
101
|
+
name: 'NotFoundError',
|
|
102
|
+
message: 'User 987fcdeb-51a2-3b4c-d567-890123456789 not found',
|
|
103
|
+
},
|
|
104
|
+
};
|
|
105
|
+
// Act
|
|
106
|
+
const hash1 = service.generateFamilyHash(entry1);
|
|
107
|
+
const hash2 = service.generateFamilyHash(entry2);
|
|
108
|
+
// Assert
|
|
109
|
+
expect(hash1).toBe(hash2);
|
|
110
|
+
});
|
|
111
|
+
it('should normalize error messages with numbers', () => {
|
|
112
|
+
// Arrange
|
|
113
|
+
const entry1 = {
|
|
114
|
+
id: 1,
|
|
115
|
+
type: 'exception',
|
|
116
|
+
timestamp: new Date().toISOString(),
|
|
117
|
+
payload: {
|
|
118
|
+
name: 'Error',
|
|
119
|
+
message: 'Failed to process item 12345',
|
|
120
|
+
},
|
|
121
|
+
};
|
|
122
|
+
const entry2 = {
|
|
123
|
+
id: 2,
|
|
124
|
+
type: 'exception',
|
|
125
|
+
timestamp: new Date().toISOString(),
|
|
126
|
+
payload: {
|
|
127
|
+
name: 'Error',
|
|
128
|
+
message: 'Failed to process item 67890',
|
|
129
|
+
},
|
|
130
|
+
};
|
|
131
|
+
// Act
|
|
132
|
+
const hash1 = service.generateFamilyHash(entry1);
|
|
133
|
+
const hash2 = service.generateFamilyHash(entry2);
|
|
134
|
+
// Assert
|
|
135
|
+
expect(hash1).toBe(hash2);
|
|
136
|
+
});
|
|
137
|
+
});
|
|
138
|
+
describe('Query Entries', () => {
|
|
139
|
+
it('should generate hash for query', () => {
|
|
140
|
+
// Arrange
|
|
141
|
+
const entry = {
|
|
142
|
+
id: 1,
|
|
143
|
+
type: 'query',
|
|
144
|
+
timestamp: new Date().toISOString(),
|
|
145
|
+
payload: {
|
|
146
|
+
query: 'SELECT * FROM users WHERE id = 1',
|
|
147
|
+
duration: 10,
|
|
148
|
+
slow: false,
|
|
149
|
+
},
|
|
150
|
+
};
|
|
151
|
+
// Act
|
|
152
|
+
const hash = service.generateFamilyHash(entry);
|
|
153
|
+
// Assert
|
|
154
|
+
expect(hash).toBeDefined();
|
|
155
|
+
expect(hash).toHaveLength(16);
|
|
156
|
+
});
|
|
157
|
+
it('should generate same hash for queries with different parameter values', () => {
|
|
158
|
+
// Arrange
|
|
159
|
+
const entry1 = {
|
|
160
|
+
id: 1,
|
|
161
|
+
type: 'query',
|
|
162
|
+
timestamp: new Date().toISOString(),
|
|
163
|
+
payload: {
|
|
164
|
+
query: 'SELECT * FROM users WHERE id = 1',
|
|
165
|
+
duration: 10,
|
|
166
|
+
slow: false,
|
|
167
|
+
},
|
|
168
|
+
};
|
|
169
|
+
const entry2 = {
|
|
170
|
+
id: 2,
|
|
171
|
+
type: 'query',
|
|
172
|
+
timestamp: new Date().toISOString(),
|
|
173
|
+
payload: {
|
|
174
|
+
query: 'SELECT * FROM users WHERE id = 999',
|
|
175
|
+
duration: 15,
|
|
176
|
+
slow: false,
|
|
177
|
+
},
|
|
178
|
+
};
|
|
179
|
+
// Act
|
|
180
|
+
const hash1 = service.generateFamilyHash(entry1);
|
|
181
|
+
const hash2 = service.generateFamilyHash(entry2);
|
|
182
|
+
// Assert
|
|
183
|
+
expect(hash1).toBe(hash2);
|
|
184
|
+
});
|
|
185
|
+
it('should generate same hash for queries with different string values', () => {
|
|
186
|
+
// Arrange
|
|
187
|
+
const entry1 = {
|
|
188
|
+
id: 1,
|
|
189
|
+
type: 'query',
|
|
190
|
+
timestamp: new Date().toISOString(),
|
|
191
|
+
payload: {
|
|
192
|
+
query: "SELECT * FROM users WHERE name = 'John'",
|
|
193
|
+
duration: 10,
|
|
194
|
+
slow: false,
|
|
195
|
+
},
|
|
196
|
+
};
|
|
197
|
+
const entry2 = {
|
|
198
|
+
id: 2,
|
|
199
|
+
type: 'query',
|
|
200
|
+
timestamp: new Date().toISOString(),
|
|
201
|
+
payload: {
|
|
202
|
+
query: "SELECT * FROM users WHERE name = 'Jane'",
|
|
203
|
+
duration: 10,
|
|
204
|
+
slow: false,
|
|
205
|
+
},
|
|
206
|
+
};
|
|
207
|
+
// Act
|
|
208
|
+
const hash1 = service.generateFamilyHash(entry1);
|
|
209
|
+
const hash2 = service.generateFamilyHash(entry2);
|
|
210
|
+
// Assert
|
|
211
|
+
expect(hash1).toBe(hash2);
|
|
212
|
+
});
|
|
213
|
+
it('should normalize parameter placeholders ($1, :param, @param)', () => {
|
|
214
|
+
// Arrange
|
|
215
|
+
const entry1 = {
|
|
216
|
+
id: 1,
|
|
217
|
+
type: 'query',
|
|
218
|
+
timestamp: new Date().toISOString(),
|
|
219
|
+
payload: {
|
|
220
|
+
query: 'SELECT * FROM users WHERE id = :id',
|
|
221
|
+
duration: 10,
|
|
222
|
+
slow: false,
|
|
223
|
+
},
|
|
224
|
+
};
|
|
225
|
+
const entry2 = {
|
|
226
|
+
id: 2,
|
|
227
|
+
type: 'query',
|
|
228
|
+
timestamp: new Date().toISOString(),
|
|
229
|
+
payload: {
|
|
230
|
+
query: 'SELECT * FROM users WHERE id = @id',
|
|
231
|
+
duration: 10,
|
|
232
|
+
slow: false,
|
|
233
|
+
},
|
|
234
|
+
};
|
|
235
|
+
// Act
|
|
236
|
+
const hash1 = service.generateFamilyHash(entry1);
|
|
237
|
+
const hash2 = service.generateFamilyHash(entry2);
|
|
238
|
+
// Assert - named parameters should normalize to same hash
|
|
239
|
+
expect(hash1).toBe(hash2);
|
|
240
|
+
});
|
|
241
|
+
it('should include source in hash', () => {
|
|
242
|
+
// Arrange
|
|
243
|
+
const entry1 = {
|
|
244
|
+
id: 1,
|
|
245
|
+
type: 'query',
|
|
246
|
+
timestamp: new Date().toISOString(),
|
|
247
|
+
payload: {
|
|
248
|
+
query: 'SELECT * FROM users',
|
|
249
|
+
source: 'TypeORM',
|
|
250
|
+
duration: 10,
|
|
251
|
+
slow: false,
|
|
252
|
+
},
|
|
253
|
+
};
|
|
254
|
+
const entry2 = {
|
|
255
|
+
id: 2,
|
|
256
|
+
type: 'query',
|
|
257
|
+
timestamp: new Date().toISOString(),
|
|
258
|
+
payload: {
|
|
259
|
+
query: 'SELECT * FROM users',
|
|
260
|
+
source: 'Prisma',
|
|
261
|
+
duration: 10,
|
|
262
|
+
slow: false,
|
|
263
|
+
},
|
|
264
|
+
};
|
|
265
|
+
// Act
|
|
266
|
+
const hash1 = service.generateFamilyHash(entry1);
|
|
267
|
+
const hash2 = service.generateFamilyHash(entry2);
|
|
268
|
+
// Assert
|
|
269
|
+
expect(hash1).not.toBe(hash2);
|
|
270
|
+
});
|
|
271
|
+
});
|
|
272
|
+
describe('Log Entries', () => {
|
|
273
|
+
it('should generate hash for error logs', () => {
|
|
274
|
+
// Arrange
|
|
275
|
+
const entry = {
|
|
276
|
+
id: 1,
|
|
277
|
+
type: 'log',
|
|
278
|
+
timestamp: new Date().toISOString(),
|
|
279
|
+
payload: {
|
|
280
|
+
level: 'error',
|
|
281
|
+
message: 'Database connection failed',
|
|
282
|
+
context: 'DatabaseService',
|
|
283
|
+
},
|
|
284
|
+
};
|
|
285
|
+
// Act
|
|
286
|
+
const hash = service.generateFamilyHash(entry);
|
|
287
|
+
// Assert
|
|
288
|
+
expect(hash).toBeDefined();
|
|
289
|
+
expect(hash).toHaveLength(16);
|
|
290
|
+
});
|
|
291
|
+
it('should generate hash for warn logs', () => {
|
|
292
|
+
// Arrange
|
|
293
|
+
const entry = {
|
|
294
|
+
id: 1,
|
|
295
|
+
type: 'log',
|
|
296
|
+
timestamp: new Date().toISOString(),
|
|
297
|
+
payload: {
|
|
298
|
+
level: 'warn',
|
|
299
|
+
message: 'Deprecated API usage',
|
|
300
|
+
context: 'ApiController',
|
|
301
|
+
},
|
|
302
|
+
};
|
|
303
|
+
// Act
|
|
304
|
+
const hash = service.generateFamilyHash(entry);
|
|
305
|
+
// Assert
|
|
306
|
+
expect(hash).toBeDefined();
|
|
307
|
+
});
|
|
308
|
+
it('should return undefined for info/debug/log levels', () => {
|
|
309
|
+
// Arrange
|
|
310
|
+
const entry = {
|
|
311
|
+
id: 1,
|
|
312
|
+
type: 'log',
|
|
313
|
+
timestamp: new Date().toISOString(),
|
|
314
|
+
payload: {
|
|
315
|
+
level: 'log',
|
|
316
|
+
message: 'Application started',
|
|
317
|
+
},
|
|
318
|
+
};
|
|
319
|
+
// Act
|
|
320
|
+
const hash = service.generateFamilyHash(entry);
|
|
321
|
+
// Assert
|
|
322
|
+
expect(hash).toBeUndefined();
|
|
323
|
+
});
|
|
324
|
+
it('should generate same hash for similar error logs with different dynamic values', () => {
|
|
325
|
+
// Arrange
|
|
326
|
+
const entry1 = {
|
|
327
|
+
id: 1,
|
|
328
|
+
type: 'log',
|
|
329
|
+
timestamp: new Date().toISOString(),
|
|
330
|
+
payload: {
|
|
331
|
+
level: 'error',
|
|
332
|
+
message: 'Failed to process user 123',
|
|
333
|
+
context: 'UserService',
|
|
334
|
+
},
|
|
335
|
+
};
|
|
336
|
+
const entry2 = {
|
|
337
|
+
id: 2,
|
|
338
|
+
type: 'log',
|
|
339
|
+
timestamp: new Date().toISOString(),
|
|
340
|
+
payload: {
|
|
341
|
+
level: 'error',
|
|
342
|
+
message: 'Failed to process user 456',
|
|
343
|
+
context: 'UserService',
|
|
344
|
+
},
|
|
345
|
+
};
|
|
346
|
+
// Act
|
|
347
|
+
const hash1 = service.generateFamilyHash(entry1);
|
|
348
|
+
const hash2 = service.generateFamilyHash(entry2);
|
|
349
|
+
// Assert
|
|
350
|
+
expect(hash1).toBe(hash2);
|
|
351
|
+
});
|
|
352
|
+
});
|
|
353
|
+
describe('Command Entries', () => {
|
|
354
|
+
it('should generate hash for command', () => {
|
|
355
|
+
// Arrange
|
|
356
|
+
const entry = {
|
|
357
|
+
id: 1,
|
|
358
|
+
type: 'command',
|
|
359
|
+
timestamp: new Date().toISOString(),
|
|
360
|
+
payload: {
|
|
361
|
+
name: 'CreateUserCommand',
|
|
362
|
+
handler: 'CreateUserHandler',
|
|
363
|
+
status: 'completed',
|
|
364
|
+
},
|
|
365
|
+
};
|
|
366
|
+
// Act
|
|
367
|
+
const hash = service.generateFamilyHash(entry);
|
|
368
|
+
// Assert
|
|
369
|
+
expect(hash).toBeDefined();
|
|
370
|
+
expect(hash).toHaveLength(16);
|
|
371
|
+
});
|
|
372
|
+
it('should generate same hash for same command with different parameters', () => {
|
|
373
|
+
// Arrange
|
|
374
|
+
const entry1 = {
|
|
375
|
+
id: 1,
|
|
376
|
+
type: 'command',
|
|
377
|
+
timestamp: new Date().toISOString(),
|
|
378
|
+
payload: {
|
|
379
|
+
name: 'CreateUserCommand',
|
|
380
|
+
handler: 'CreateUserHandler',
|
|
381
|
+
status: 'completed',
|
|
382
|
+
payload: { name: 'John' },
|
|
383
|
+
},
|
|
384
|
+
};
|
|
385
|
+
const entry2 = {
|
|
386
|
+
id: 2,
|
|
387
|
+
type: 'command',
|
|
388
|
+
timestamp: new Date().toISOString(),
|
|
389
|
+
payload: {
|
|
390
|
+
name: 'CreateUserCommand',
|
|
391
|
+
handler: 'CreateUserHandler',
|
|
392
|
+
status: 'completed',
|
|
393
|
+
payload: { name: 'Jane' },
|
|
394
|
+
},
|
|
395
|
+
};
|
|
396
|
+
// Act
|
|
397
|
+
const hash1 = service.generateFamilyHash(entry1);
|
|
398
|
+
const hash2 = service.generateFamilyHash(entry2);
|
|
399
|
+
// Assert
|
|
400
|
+
expect(hash1).toBe(hash2);
|
|
401
|
+
});
|
|
402
|
+
});
|
|
403
|
+
describe('Gate Entries', () => {
|
|
404
|
+
it('should generate hash for gate check', () => {
|
|
405
|
+
// Arrange
|
|
406
|
+
const entry = {
|
|
407
|
+
id: 1,
|
|
408
|
+
type: 'gate',
|
|
409
|
+
timestamp: new Date().toISOString(),
|
|
410
|
+
payload: {
|
|
411
|
+
gate: 'CanEditPost',
|
|
412
|
+
action: 'edit',
|
|
413
|
+
subject: 'Post:123',
|
|
414
|
+
allowed: true,
|
|
415
|
+
duration: 5,
|
|
416
|
+
},
|
|
417
|
+
};
|
|
418
|
+
// Act
|
|
419
|
+
const hash = service.generateFamilyHash(entry);
|
|
420
|
+
// Assert
|
|
421
|
+
expect(hash).toBeDefined();
|
|
422
|
+
expect(hash).toHaveLength(16);
|
|
423
|
+
});
|
|
424
|
+
it('should normalize subject IDs', () => {
|
|
425
|
+
// Arrange
|
|
426
|
+
const entry1 = {
|
|
427
|
+
id: 1,
|
|
428
|
+
type: 'gate',
|
|
429
|
+
timestamp: new Date().toISOString(),
|
|
430
|
+
payload: {
|
|
431
|
+
gate: 'CanEditPost',
|
|
432
|
+
action: 'edit',
|
|
433
|
+
subject: 'Post:123',
|
|
434
|
+
allowed: true,
|
|
435
|
+
duration: 5,
|
|
436
|
+
},
|
|
437
|
+
};
|
|
438
|
+
const entry2 = {
|
|
439
|
+
id: 2,
|
|
440
|
+
type: 'gate',
|
|
441
|
+
timestamp: new Date().toISOString(),
|
|
442
|
+
payload: {
|
|
443
|
+
gate: 'CanEditPost',
|
|
444
|
+
action: 'edit',
|
|
445
|
+
subject: 'Post:456',
|
|
446
|
+
allowed: false,
|
|
447
|
+
duration: 5,
|
|
448
|
+
},
|
|
449
|
+
};
|
|
450
|
+
// Act
|
|
451
|
+
const hash1 = service.generateFamilyHash(entry1);
|
|
452
|
+
const hash2 = service.generateFamilyHash(entry2);
|
|
453
|
+
// Assert
|
|
454
|
+
expect(hash1).toBe(hash2);
|
|
455
|
+
});
|
|
456
|
+
});
|
|
457
|
+
describe('Batch Entries', () => {
|
|
458
|
+
it('should generate hash for batch operation', () => {
|
|
459
|
+
// Arrange
|
|
460
|
+
const entry = {
|
|
461
|
+
id: 1,
|
|
462
|
+
type: 'batch',
|
|
463
|
+
timestamp: new Date().toISOString(),
|
|
464
|
+
payload: {
|
|
465
|
+
name: 'ImportUsers',
|
|
466
|
+
operation: 'import',
|
|
467
|
+
totalItems: 100,
|
|
468
|
+
status: 'completed',
|
|
469
|
+
},
|
|
470
|
+
};
|
|
471
|
+
// Act
|
|
472
|
+
const hash = service.generateFamilyHash(entry);
|
|
473
|
+
// Assert
|
|
474
|
+
expect(hash).toBeDefined();
|
|
475
|
+
expect(hash).toHaveLength(16);
|
|
476
|
+
});
|
|
477
|
+
it('should generate same hash for same batch type', () => {
|
|
478
|
+
// Arrange
|
|
479
|
+
const entry1 = {
|
|
480
|
+
id: 1,
|
|
481
|
+
type: 'batch',
|
|
482
|
+
timestamp: new Date().toISOString(),
|
|
483
|
+
payload: {
|
|
484
|
+
name: 'ImportUsers',
|
|
485
|
+
operation: 'import',
|
|
486
|
+
totalItems: 100,
|
|
487
|
+
status: 'completed',
|
|
488
|
+
},
|
|
489
|
+
};
|
|
490
|
+
const entry2 = {
|
|
491
|
+
id: 2,
|
|
492
|
+
type: 'batch',
|
|
493
|
+
timestamp: new Date().toISOString(),
|
|
494
|
+
payload: {
|
|
495
|
+
name: 'ImportUsers',
|
|
496
|
+
operation: 'import',
|
|
497
|
+
totalItems: 500,
|
|
498
|
+
status: 'failed',
|
|
499
|
+
},
|
|
500
|
+
};
|
|
501
|
+
// Act
|
|
502
|
+
const hash1 = service.generateFamilyHash(entry1);
|
|
503
|
+
const hash2 = service.generateFamilyHash(entry2);
|
|
504
|
+
// Assert
|
|
505
|
+
expect(hash1).toBe(hash2);
|
|
506
|
+
});
|
|
507
|
+
});
|
|
508
|
+
describe('Unsupported Entry Types', () => {
|
|
509
|
+
it('should return undefined for request entries', () => {
|
|
510
|
+
// Arrange
|
|
511
|
+
const entry = {
|
|
512
|
+
id: 1,
|
|
513
|
+
type: 'request',
|
|
514
|
+
timestamp: new Date().toISOString(),
|
|
515
|
+
payload: {
|
|
516
|
+
method: 'GET',
|
|
517
|
+
url: '/api/users',
|
|
518
|
+
path: '/api/users',
|
|
519
|
+
query: {},
|
|
520
|
+
params: {},
|
|
521
|
+
headers: {},
|
|
522
|
+
statusCode: 200,
|
|
523
|
+
duration: 50,
|
|
524
|
+
memory: 0,
|
|
525
|
+
},
|
|
526
|
+
};
|
|
527
|
+
// Act
|
|
528
|
+
const hash = service.generateFamilyHash(entry);
|
|
529
|
+
// Assert
|
|
530
|
+
expect(hash).toBeUndefined();
|
|
531
|
+
});
|
|
532
|
+
it('should return undefined for cache entries', () => {
|
|
533
|
+
// Arrange
|
|
534
|
+
const entry = {
|
|
535
|
+
id: 1,
|
|
536
|
+
type: 'cache',
|
|
537
|
+
timestamp: new Date().toISOString(),
|
|
538
|
+
payload: {
|
|
539
|
+
key: 'user:1',
|
|
540
|
+
operation: 'get',
|
|
541
|
+
hit: true,
|
|
542
|
+
},
|
|
543
|
+
};
|
|
544
|
+
// Act
|
|
545
|
+
const hash = service.generateFamilyHash(entry);
|
|
546
|
+
// Assert
|
|
547
|
+
expect(hash).toBeUndefined();
|
|
548
|
+
});
|
|
549
|
+
it('should return undefined for event entries', () => {
|
|
550
|
+
// Arrange
|
|
551
|
+
const entry = {
|
|
552
|
+
id: 1,
|
|
553
|
+
type: 'event',
|
|
554
|
+
timestamp: new Date().toISOString(),
|
|
555
|
+
payload: {
|
|
556
|
+
name: 'user.created',
|
|
557
|
+
payload: {},
|
|
558
|
+
listeners: ['Handler1'],
|
|
559
|
+
duration: 10,
|
|
560
|
+
},
|
|
561
|
+
};
|
|
562
|
+
// Act
|
|
563
|
+
const hash = service.generateFamilyHash(entry);
|
|
564
|
+
// Assert
|
|
565
|
+
expect(hash).toBeUndefined();
|
|
566
|
+
});
|
|
567
|
+
});
|
|
568
|
+
});
|
|
569
|
+
describe('extractStackInfo', () => {
|
|
570
|
+
it('should extract file and line from Node.js stack trace', () => {
|
|
571
|
+
// Arrange
|
|
572
|
+
const stack = 'Error: Something went wrong\n at Function.name (/path/to/src/service.ts:42:15)';
|
|
573
|
+
// Act
|
|
574
|
+
const result = service['extractStackInfo'](stack);
|
|
575
|
+
// Assert
|
|
576
|
+
expect(result).toBeDefined();
|
|
577
|
+
expect(result?.file).toContain('src/service.ts');
|
|
578
|
+
expect(result?.line).toBe('42');
|
|
579
|
+
});
|
|
580
|
+
it('should return undefined for empty stack', () => {
|
|
581
|
+
// Act
|
|
582
|
+
const result = service['extractStackInfo'](undefined);
|
|
583
|
+
// Assert
|
|
584
|
+
expect(result).toBeUndefined();
|
|
585
|
+
});
|
|
586
|
+
it('should return undefined for invalid stack format', () => {
|
|
587
|
+
// Arrange
|
|
588
|
+
const stack = 'Not a valid stack trace';
|
|
589
|
+
// Act
|
|
590
|
+
const result = service['extractStackInfo'](stack);
|
|
591
|
+
// Assert
|
|
592
|
+
expect(result).toBeUndefined();
|
|
593
|
+
});
|
|
594
|
+
});
|
|
595
|
+
describe('normalizeFilePath', () => {
|
|
596
|
+
it('should remove absolute path prefix before src', () => {
|
|
597
|
+
// Arrange
|
|
598
|
+
const path = '/Users/user/project/src/services/user.service.ts';
|
|
599
|
+
// Act
|
|
600
|
+
const result = service['normalizeFilePath'](path);
|
|
601
|
+
// Assert
|
|
602
|
+
expect(result).toBe('src/services/user.service.ts');
|
|
603
|
+
});
|
|
604
|
+
it('should mark node_modules as external', () => {
|
|
605
|
+
// Arrange
|
|
606
|
+
const path = '/path/to/node_modules/lodash/index.js';
|
|
607
|
+
// Act
|
|
608
|
+
const result = service['normalizeFilePath'](path);
|
|
609
|
+
// Assert
|
|
610
|
+
expect(result).toBe('[node_modules]/lodash');
|
|
611
|
+
});
|
|
612
|
+
});
|
|
613
|
+
describe('normalizeQuery', () => {
|
|
614
|
+
it('should normalize whitespace', () => {
|
|
615
|
+
// Arrange
|
|
616
|
+
const query = 'SELECT * FROM users WHERE id = 1';
|
|
617
|
+
// Act
|
|
618
|
+
const result = service['normalizeQuery'](query);
|
|
619
|
+
// Assert
|
|
620
|
+
expect(result).toBe('select * from users where id = ?');
|
|
621
|
+
});
|
|
622
|
+
it('should replace string literals', () => {
|
|
623
|
+
// Arrange
|
|
624
|
+
const query = "SELECT * FROM users WHERE name = 'John'";
|
|
625
|
+
// Act
|
|
626
|
+
const result = service['normalizeQuery'](query);
|
|
627
|
+
// Assert
|
|
628
|
+
expect(result).toBe('select * from users where name = ?');
|
|
629
|
+
});
|
|
630
|
+
it('should replace numeric literals', () => {
|
|
631
|
+
// Arrange
|
|
632
|
+
const query = 'SELECT * FROM users WHERE id = 123 AND age > 18';
|
|
633
|
+
// Act
|
|
634
|
+
const result = service['normalizeQuery'](query);
|
|
635
|
+
// Assert
|
|
636
|
+
expect(result).toBe('select * from users where id = ? and age > ?');
|
|
637
|
+
});
|
|
638
|
+
it('should replace PostgreSQL parameter placeholders ($1, $2)', () => {
|
|
639
|
+
// Arrange
|
|
640
|
+
const query = 'SELECT * FROM users WHERE id = $1 AND name = $2';
|
|
641
|
+
// Act
|
|
642
|
+
const result = service['normalizeQuery'](query);
|
|
643
|
+
// Assert - numeric replacement runs first, so $1 becomes $?
|
|
644
|
+
expect(result).toBe('select * from users where id = $? and name = $?');
|
|
645
|
+
});
|
|
646
|
+
it('should replace named parameters (:param)', () => {
|
|
647
|
+
// Arrange
|
|
648
|
+
const query = 'SELECT * FROM users WHERE id = :id AND name = :name';
|
|
649
|
+
// Act
|
|
650
|
+
const result = service['normalizeQuery'](query);
|
|
651
|
+
// Assert
|
|
652
|
+
expect(result).toBe('select * from users where id = ? and name = ?');
|
|
653
|
+
});
|
|
654
|
+
});
|
|
655
|
+
describe('normalizeErrorMessage', () => {
|
|
656
|
+
it('should replace UUIDs', () => {
|
|
657
|
+
// Arrange
|
|
658
|
+
const message = 'User 123e4567-e89b-12d3-a456-426614174000 not found';
|
|
659
|
+
// Act
|
|
660
|
+
const result = service['normalizeErrorMessage'](message);
|
|
661
|
+
// Assert
|
|
662
|
+
expect(result).toBe('User [UUID] not found');
|
|
663
|
+
});
|
|
664
|
+
it('should replace numbers', () => {
|
|
665
|
+
// Arrange
|
|
666
|
+
const message = 'Failed to process order 12345';
|
|
667
|
+
// Act
|
|
668
|
+
const result = service['normalizeErrorMessage'](message);
|
|
669
|
+
// Assert
|
|
670
|
+
expect(result).toBe('Failed to process order [N]');
|
|
671
|
+
});
|
|
672
|
+
it('should replace email addresses', () => {
|
|
673
|
+
// Arrange
|
|
674
|
+
const message = 'Failed to send email to user@example.com';
|
|
675
|
+
// Act
|
|
676
|
+
const result = service['normalizeErrorMessage'](message);
|
|
677
|
+
// Assert
|
|
678
|
+
expect(result).toBe('Failed to send email to [EMAIL]');
|
|
679
|
+
});
|
|
680
|
+
it('should replace URLs', () => {
|
|
681
|
+
// Arrange
|
|
682
|
+
const message = 'Failed to connect to https://api.example.com/v1/users';
|
|
683
|
+
// Act
|
|
684
|
+
const result = service['normalizeErrorMessage'](message);
|
|
685
|
+
// Assert
|
|
686
|
+
expect(result).toBe('Failed to connect to [URL]');
|
|
687
|
+
});
|
|
688
|
+
it('should replace file paths', () => {
|
|
689
|
+
// Arrange
|
|
690
|
+
const message = 'Cannot read file /path/to/file.txt';
|
|
691
|
+
// Act
|
|
692
|
+
const result = service['normalizeErrorMessage'](message);
|
|
693
|
+
// Assert
|
|
694
|
+
expect(result).toBe('Cannot read file [PATH]');
|
|
695
|
+
});
|
|
696
|
+
it('should replace quoted strings', () => {
|
|
697
|
+
// Arrange
|
|
698
|
+
const message = "Failed to parse 'invalid json' value";
|
|
699
|
+
// Act
|
|
700
|
+
const result = service['normalizeErrorMessage'](message);
|
|
701
|
+
// Assert
|
|
702
|
+
expect(result).toBe('Failed to parse [STR] value');
|
|
703
|
+
});
|
|
704
|
+
});
|
|
705
|
+
describe('normalizeSubject', () => {
|
|
706
|
+
it('should replace UUIDs in subject', () => {
|
|
707
|
+
// Arrange
|
|
708
|
+
const subject = 'User:123e4567-e89b-12d3-a456-426614174000';
|
|
709
|
+
// Act
|
|
710
|
+
const result = service['normalizeSubject'](subject);
|
|
711
|
+
// Assert
|
|
712
|
+
expect(result).toBe('User:[ID]');
|
|
713
|
+
});
|
|
714
|
+
it('should replace numeric IDs', () => {
|
|
715
|
+
// Arrange
|
|
716
|
+
const subject = 'Post:12345';
|
|
717
|
+
// Act
|
|
718
|
+
const result = service['normalizeSubject'](subject);
|
|
719
|
+
// Assert
|
|
720
|
+
expect(result).toBe('Post:[ID]');
|
|
721
|
+
});
|
|
722
|
+
});
|
|
723
|
+
describe('hash', () => {
|
|
724
|
+
it('should generate consistent 16-character hash', () => {
|
|
725
|
+
// Arrange
|
|
726
|
+
const input = 'test input';
|
|
727
|
+
// Act
|
|
728
|
+
const hash1 = service['hash'](input);
|
|
729
|
+
const hash2 = service['hash'](input);
|
|
730
|
+
// Assert
|
|
731
|
+
expect(hash1).toBe(hash2);
|
|
732
|
+
expect(hash1).toHaveLength(16);
|
|
733
|
+
});
|
|
734
|
+
it('should generate different hash for different inputs', () => {
|
|
735
|
+
// Arrange
|
|
736
|
+
const input1 = 'input one';
|
|
737
|
+
const input2 = 'input two';
|
|
738
|
+
// Act
|
|
739
|
+
const hash1 = service['hash'](input1);
|
|
740
|
+
const hash2 = service['hash'](input2);
|
|
741
|
+
// Assert
|
|
742
|
+
expect(hash1).not.toBe(hash2);
|
|
743
|
+
});
|
|
744
|
+
});
|
|
745
|
+
// ============================================================================
|
|
746
|
+
// Edge Cases and Branch Coverage
|
|
747
|
+
// ============================================================================
|
|
748
|
+
describe('edge cases', () => {
|
|
749
|
+
describe('log entries', () => {
|
|
750
|
+
it('should return undefined for log level logs', () => {
|
|
751
|
+
// Arrange - 'log' level (not error/warn) should return undefined
|
|
752
|
+
const entry = {
|
|
753
|
+
id: 1,
|
|
754
|
+
type: 'log',
|
|
755
|
+
payload: {
|
|
756
|
+
level: 'log',
|
|
757
|
+
message: 'Log message',
|
|
758
|
+
context: 'TestContext',
|
|
759
|
+
},
|
|
760
|
+
};
|
|
761
|
+
// Act
|
|
762
|
+
const hash = service.generateFamilyHash(entry);
|
|
763
|
+
// Assert
|
|
764
|
+
expect(hash).toBeUndefined();
|
|
765
|
+
});
|
|
766
|
+
it('should return undefined for debug level logs', () => {
|
|
767
|
+
// Arrange
|
|
768
|
+
const entry = {
|
|
769
|
+
id: 1,
|
|
770
|
+
type: 'log',
|
|
771
|
+
payload: {
|
|
772
|
+
level: 'debug',
|
|
773
|
+
message: 'Debug message',
|
|
774
|
+
context: 'TestContext',
|
|
775
|
+
},
|
|
776
|
+
};
|
|
777
|
+
// Act
|
|
778
|
+
const hash = service.generateFamilyHash(entry);
|
|
779
|
+
// Assert
|
|
780
|
+
expect(hash).toBeUndefined();
|
|
781
|
+
});
|
|
782
|
+
it('should return undefined for verbose level logs', () => {
|
|
783
|
+
// Arrange
|
|
784
|
+
const entry = {
|
|
785
|
+
id: 1,
|
|
786
|
+
type: 'log',
|
|
787
|
+
payload: {
|
|
788
|
+
level: 'verbose',
|
|
789
|
+
message: 'Verbose message',
|
|
790
|
+
context: 'TestContext',
|
|
791
|
+
},
|
|
792
|
+
};
|
|
793
|
+
// Act
|
|
794
|
+
const hash = service.generateFamilyHash(entry);
|
|
795
|
+
// Assert
|
|
796
|
+
expect(hash).toBeUndefined();
|
|
797
|
+
});
|
|
798
|
+
it('should generate hash for warn level logs', () => {
|
|
799
|
+
// Arrange
|
|
800
|
+
const entry = {
|
|
801
|
+
id: 1,
|
|
802
|
+
type: 'log',
|
|
803
|
+
payload: {
|
|
804
|
+
level: 'warn',
|
|
805
|
+
message: 'Warning message',
|
|
806
|
+
context: 'TestContext',
|
|
807
|
+
},
|
|
808
|
+
};
|
|
809
|
+
// Act
|
|
810
|
+
const hash = service.generateFamilyHash(entry);
|
|
811
|
+
// Assert
|
|
812
|
+
expect(hash).toBeDefined();
|
|
813
|
+
expect(hash).toHaveLength(16);
|
|
814
|
+
});
|
|
815
|
+
it('should handle log without context', () => {
|
|
816
|
+
// Arrange
|
|
817
|
+
const entry = {
|
|
818
|
+
id: 1,
|
|
819
|
+
type: 'log',
|
|
820
|
+
payload: {
|
|
821
|
+
level: 'error',
|
|
822
|
+
message: 'Error without context',
|
|
823
|
+
},
|
|
824
|
+
};
|
|
825
|
+
// Act
|
|
826
|
+
const hash = service.generateFamilyHash(entry);
|
|
827
|
+
// Assert
|
|
828
|
+
expect(hash).toBeDefined();
|
|
829
|
+
});
|
|
830
|
+
});
|
|
831
|
+
describe('exception entries', () => {
|
|
832
|
+
it('should handle exception without stack trace', () => {
|
|
833
|
+
// Arrange
|
|
834
|
+
const entry = {
|
|
835
|
+
id: 1,
|
|
836
|
+
type: 'exception',
|
|
837
|
+
payload: {
|
|
838
|
+
name: 'Error',
|
|
839
|
+
message: 'Error without stack',
|
|
840
|
+
},
|
|
841
|
+
};
|
|
842
|
+
// Act
|
|
843
|
+
const hash = service.generateFamilyHash(entry);
|
|
844
|
+
// Assert
|
|
845
|
+
expect(hash).toBeDefined();
|
|
846
|
+
});
|
|
847
|
+
it('should handle exception with empty stack', () => {
|
|
848
|
+
// Arrange
|
|
849
|
+
const entry = {
|
|
850
|
+
id: 1,
|
|
851
|
+
type: 'exception',
|
|
852
|
+
payload: {
|
|
853
|
+
name: 'Error',
|
|
854
|
+
message: 'Error message',
|
|
855
|
+
stack: '',
|
|
856
|
+
},
|
|
857
|
+
};
|
|
858
|
+
// Act
|
|
859
|
+
const hash = service.generateFamilyHash(entry);
|
|
860
|
+
// Assert
|
|
861
|
+
expect(hash).toBeDefined();
|
|
862
|
+
});
|
|
863
|
+
it('should handle exception with malformed stack', () => {
|
|
864
|
+
// Arrange
|
|
865
|
+
const entry = {
|
|
866
|
+
id: 1,
|
|
867
|
+
type: 'exception',
|
|
868
|
+
payload: {
|
|
869
|
+
name: 'Error',
|
|
870
|
+
message: 'Error message',
|
|
871
|
+
stack: 'Just some random text without file info',
|
|
872
|
+
},
|
|
873
|
+
};
|
|
874
|
+
// Act
|
|
875
|
+
const hash = service.generateFamilyHash(entry);
|
|
876
|
+
// Assert
|
|
877
|
+
expect(hash).toBeDefined();
|
|
878
|
+
});
|
|
879
|
+
});
|
|
880
|
+
describe('query entries', () => {
|
|
881
|
+
it('should handle query without source', () => {
|
|
882
|
+
// Arrange
|
|
883
|
+
const entry = {
|
|
884
|
+
id: 1,
|
|
885
|
+
type: 'query',
|
|
886
|
+
payload: {
|
|
887
|
+
query: 'SELECT * FROM users',
|
|
888
|
+
duration: 10,
|
|
889
|
+
slow: false,
|
|
890
|
+
},
|
|
891
|
+
};
|
|
892
|
+
// Act
|
|
893
|
+
const hash = service.generateFamilyHash(entry);
|
|
894
|
+
// Assert
|
|
895
|
+
expect(hash).toBeDefined();
|
|
896
|
+
});
|
|
897
|
+
it('should handle query with source', () => {
|
|
898
|
+
// Arrange
|
|
899
|
+
const entry = {
|
|
900
|
+
id: 1,
|
|
901
|
+
type: 'query',
|
|
902
|
+
payload: {
|
|
903
|
+
query: 'SELECT * FROM users',
|
|
904
|
+
duration: 10,
|
|
905
|
+
slow: false,
|
|
906
|
+
source: 'UserRepository',
|
|
907
|
+
},
|
|
908
|
+
};
|
|
909
|
+
// Act
|
|
910
|
+
const hash = service.generateFamilyHash(entry);
|
|
911
|
+
// Assert
|
|
912
|
+
expect(hash).toBeDefined();
|
|
913
|
+
});
|
|
914
|
+
});
|
|
915
|
+
describe('command entries', () => {
|
|
916
|
+
it('should handle command without handler', () => {
|
|
917
|
+
// Arrange
|
|
918
|
+
const entry = {
|
|
919
|
+
id: 1,
|
|
920
|
+
type: 'command',
|
|
921
|
+
payload: {
|
|
922
|
+
name: 'create:user',
|
|
923
|
+
exitCode: 0,
|
|
924
|
+
duration: 100,
|
|
925
|
+
},
|
|
926
|
+
};
|
|
927
|
+
// Act
|
|
928
|
+
const hash = service.generateFamilyHash(entry);
|
|
929
|
+
// Assert
|
|
930
|
+
expect(hash).toBeDefined();
|
|
931
|
+
});
|
|
932
|
+
it('should handle command with handler', () => {
|
|
933
|
+
// Arrange
|
|
934
|
+
const entry = {
|
|
935
|
+
id: 1,
|
|
936
|
+
type: 'command',
|
|
937
|
+
payload: {
|
|
938
|
+
name: 'create:user',
|
|
939
|
+
handler: 'CreateUserHandler',
|
|
940
|
+
exitCode: 0,
|
|
941
|
+
duration: 100,
|
|
942
|
+
},
|
|
943
|
+
};
|
|
944
|
+
// Act
|
|
945
|
+
const hash = service.generateFamilyHash(entry);
|
|
946
|
+
// Assert
|
|
947
|
+
expect(hash).toBeDefined();
|
|
948
|
+
});
|
|
949
|
+
});
|
|
950
|
+
describe('gate entries', () => {
|
|
951
|
+
it('should handle gate without subject', () => {
|
|
952
|
+
// Arrange
|
|
953
|
+
const entry = {
|
|
954
|
+
id: 1,
|
|
955
|
+
type: 'gate',
|
|
956
|
+
payload: {
|
|
957
|
+
gate: 'UserGate',
|
|
958
|
+
action: 'view',
|
|
959
|
+
result: true,
|
|
960
|
+
duration: 5,
|
|
961
|
+
},
|
|
962
|
+
};
|
|
963
|
+
// Act
|
|
964
|
+
const hash = service.generateFamilyHash(entry);
|
|
965
|
+
// Assert
|
|
966
|
+
expect(hash).toBeDefined();
|
|
967
|
+
});
|
|
968
|
+
it('should handle gate with subject', () => {
|
|
969
|
+
// Arrange
|
|
970
|
+
const entry = {
|
|
971
|
+
id: 1,
|
|
972
|
+
type: 'gate',
|
|
973
|
+
payload: {
|
|
974
|
+
gate: 'UserGate',
|
|
975
|
+
action: 'edit',
|
|
976
|
+
subject: 'User:123',
|
|
977
|
+
result: true,
|
|
978
|
+
duration: 5,
|
|
979
|
+
},
|
|
980
|
+
};
|
|
981
|
+
// Act
|
|
982
|
+
const hash = service.generateFamilyHash(entry);
|
|
983
|
+
// Assert
|
|
984
|
+
expect(hash).toBeDefined();
|
|
985
|
+
});
|
|
986
|
+
it('should normalize gate subjects with IDs', () => {
|
|
987
|
+
// Arrange
|
|
988
|
+
const entry1 = {
|
|
989
|
+
id: 1,
|
|
990
|
+
type: 'gate',
|
|
991
|
+
payload: {
|
|
992
|
+
gate: 'PostGate',
|
|
993
|
+
action: 'delete',
|
|
994
|
+
subject: 'Post:12345',
|
|
995
|
+
result: false,
|
|
996
|
+
duration: 5,
|
|
997
|
+
},
|
|
998
|
+
};
|
|
999
|
+
const entry2 = {
|
|
1000
|
+
id: 2,
|
|
1001
|
+
type: 'gate',
|
|
1002
|
+
payload: {
|
|
1003
|
+
gate: 'PostGate',
|
|
1004
|
+
action: 'delete',
|
|
1005
|
+
subject: 'Post:67890',
|
|
1006
|
+
result: true,
|
|
1007
|
+
duration: 3,
|
|
1008
|
+
},
|
|
1009
|
+
};
|
|
1010
|
+
// Act
|
|
1011
|
+
const hash1 = service.generateFamilyHash(entry1);
|
|
1012
|
+
const hash2 = service.generateFamilyHash(entry2);
|
|
1013
|
+
// Assert - should have same hash (ID normalized)
|
|
1014
|
+
expect(hash1).toBe(hash2);
|
|
1015
|
+
});
|
|
1016
|
+
});
|
|
1017
|
+
describe('unsupported entry types', () => {
|
|
1018
|
+
it('should return undefined for request entries', () => {
|
|
1019
|
+
// Arrange
|
|
1020
|
+
const entry = {
|
|
1021
|
+
id: 1,
|
|
1022
|
+
type: 'request',
|
|
1023
|
+
payload: {
|
|
1024
|
+
method: 'GET',
|
|
1025
|
+
url: '/api',
|
|
1026
|
+
path: '/api',
|
|
1027
|
+
query: {},
|
|
1028
|
+
params: {},
|
|
1029
|
+
headers: {},
|
|
1030
|
+
statusCode: 200,
|
|
1031
|
+
duration: 50,
|
|
1032
|
+
memory: 1024,
|
|
1033
|
+
},
|
|
1034
|
+
};
|
|
1035
|
+
// Act
|
|
1036
|
+
const hash = service.generateFamilyHash(entry);
|
|
1037
|
+
// Assert
|
|
1038
|
+
expect(hash).toBeUndefined();
|
|
1039
|
+
});
|
|
1040
|
+
it('should return undefined for cache entries', () => {
|
|
1041
|
+
// Arrange
|
|
1042
|
+
const entry = {
|
|
1043
|
+
id: 1,
|
|
1044
|
+
type: 'cache',
|
|
1045
|
+
payload: {
|
|
1046
|
+
action: 'get',
|
|
1047
|
+
key: 'user:123',
|
|
1048
|
+
hit: true,
|
|
1049
|
+
duration: 2,
|
|
1050
|
+
},
|
|
1051
|
+
};
|
|
1052
|
+
// Act
|
|
1053
|
+
const hash = service.generateFamilyHash(entry);
|
|
1054
|
+
// Assert
|
|
1055
|
+
expect(hash).toBeUndefined();
|
|
1056
|
+
});
|
|
1057
|
+
it('should return undefined for event entries', () => {
|
|
1058
|
+
// Arrange
|
|
1059
|
+
const entry = {
|
|
1060
|
+
id: 1,
|
|
1061
|
+
type: 'event',
|
|
1062
|
+
payload: {
|
|
1063
|
+
name: 'user.created',
|
|
1064
|
+
payload: {},
|
|
1065
|
+
listeners: [],
|
|
1066
|
+
duration: 10,
|
|
1067
|
+
},
|
|
1068
|
+
};
|
|
1069
|
+
// Act
|
|
1070
|
+
const hash = service.generateFamilyHash(entry);
|
|
1071
|
+
// Assert
|
|
1072
|
+
expect(hash).toBeUndefined();
|
|
1073
|
+
});
|
|
1074
|
+
});
|
|
1075
|
+
});
|
|
1076
|
+
describe('normalizeSubject', () => {
|
|
1077
|
+
it('should normalize subject with numeric ID', () => {
|
|
1078
|
+
// Act
|
|
1079
|
+
const result = service['normalizeSubject']('User:12345');
|
|
1080
|
+
// Assert - actual implementation uses [ID] placeholder
|
|
1081
|
+
expect(result).toBe('User:[ID]');
|
|
1082
|
+
});
|
|
1083
|
+
it('should normalize subject with UUID', () => {
|
|
1084
|
+
// Act
|
|
1085
|
+
const result = service['normalizeSubject']('User:550e8400-e29b-41d4-a716-446655440000');
|
|
1086
|
+
// Assert
|
|
1087
|
+
expect(result).toBe('User:[ID]');
|
|
1088
|
+
});
|
|
1089
|
+
it('should handle subject without ID separator', () => {
|
|
1090
|
+
// Act
|
|
1091
|
+
const result = service['normalizeSubject']('SomeClass');
|
|
1092
|
+
// Assert
|
|
1093
|
+
expect(result).toBe('SomeClass');
|
|
1094
|
+
});
|
|
1095
|
+
});
|
|
1096
|
+
describe('normalizeFilePath', () => {
|
|
1097
|
+
it('should normalize file paths', () => {
|
|
1098
|
+
// Act
|
|
1099
|
+
const result = service['normalizeFilePath']('/Users/dev/project/src/services/user.service.ts');
|
|
1100
|
+
// Assert - implementation extracts from src/
|
|
1101
|
+
expect(result).toContain('user.service.ts');
|
|
1102
|
+
});
|
|
1103
|
+
it('should handle Windows paths', () => {
|
|
1104
|
+
// Act
|
|
1105
|
+
const result = service['normalizeFilePath']('C:\\Projects\\app\\src\\service.ts');
|
|
1106
|
+
// Assert
|
|
1107
|
+
expect(result).toContain('service.ts');
|
|
1108
|
+
});
|
|
1109
|
+
it('should handle simple filename', () => {
|
|
1110
|
+
// Act
|
|
1111
|
+
const result = service['normalizeFilePath']('file.ts');
|
|
1112
|
+
// Assert
|
|
1113
|
+
expect(result).toBe('file.ts');
|
|
1114
|
+
});
|
|
1115
|
+
});
|
|
1116
|
+
});
|
|
1117
|
+
//# sourceMappingURL=family-hash.service.spec.js.map
|