@mojaloop/central-ledger 19.14.0 → 20.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/.grype.yaml +3 -0
- package/.license-scanner.json +16 -0
- package/.ncurc.yaml +19 -13
- package/.nvmrc +1 -1
- package/.nycrc.yml +14 -2
- package/CHANGELOG.md +51 -0
- package/Dockerfile +13 -10
- package/README.md +39 -89
- package/audit-ci.jsonc +1 -1
- package/config/default.json +60 -3
- package/config/deprecated.default-settlement.json +160 -0
- package/docker/ml-api-adapter/default.json +28 -0
- package/docker-compose.yml +6 -0
- package/nodemon.json +6 -0
- package/package.json +128 -64
- package/{sbom-v19.13.2.csv → sbom-v20.0.0.csv} +886 -736
- package/scripts/_wait4_all.js +5 -5
- package/scripts/transferSettlementTemp/interchangeFeeCalculation.js +51 -0
- package/src/api/index.ts +30 -0
- package/src/api/interface/swagger.json +2249 -2054
- package/src/api/participants/routes.js +1 -1
- package/src/api/root/handler.int.ts +55 -0
- package/src/api/routes.js +7 -6
- package/src/api/server.ts +27 -0
- package/src/api/server.unit.ts +16 -0
- package/src/api/settlementModels/routes.js +4 -4
- package/src/domain/participant/index.d.ts +47 -0
- package/src/domain/participant/index.int.ts +724 -0
- package/src/domain/participant/index.js +4 -5
- package/src/domain/position/fx-prepare.js +1 -1
- package/src/domain/position/fx-timeout-reserved.js +6 -0
- package/src/domain/position/prepare.js +1 -1
- package/src/handlers/admin/handler.js +1 -1
- package/src/handlers/index.js +30 -0
- package/src/handlers/positions/handler.js +0 -2
- package/src/handlers/positions/handlerBatch.js +5 -5
- package/src/handlers/register.js +44 -29
- package/src/handlers/timeouts/handler.js +1 -4
- package/src/handlers/transfers/fx-abort.int.ts +209 -0
- package/src/handlers/transfers/fx-handlers.int.ts +275 -0
- package/src/handlers/transfers/fx-timeout.int.ts +284 -0
- package/src/handlers/transfers/handler.js +1 -3
- package/src/handlers/transfers/handlers.int.ts +538 -0
- package/src/handlers/transfers/prepare.int.ts +1283 -0
- package/src/handlers/transfers/prepare.js +2 -2
- package/src/knexfile.js +19 -0
- package/src/lib/cache.js +1 -1
- package/src/lib/config/index.ts +60 -0
- package/src/lib/config/resolver.ts +231 -0
- package/src/lib/config/resolver.unit.ts +72 -0
- package/src/lib/config/types.ts +372 -0
- package/src/lib/config/util.ts +523 -0
- package/src/lib/config/util.unit.ts +825 -0
- package/src/lib/migrator.js +3 -3
- package/src/lib/proxyCache.js +3 -3
- package/{migrations → src/migrations}/100100_event.js +1 -1
- package/{migrations → src/migrations}/110100_contactType.js +1 -1
- package/{migrations → src/migrations}/110200_currency.js +1 -1
- package/{migrations → src/migrations}/110201_currency-scale.js +1 -1
- package/{migrations → src/migrations}/110300_endpointType.js +1 -1
- package/{migrations → src/migrations}/110400_ledgerEntryType.js +1 -1
- package/{migrations → src/migrations}/110450_ledgerAccountType.js +1 -1
- package/{migrations → src/migrations}/110500_participantLimitType.js +1 -1
- package/{migrations → src/migrations}/110600_transferParticipantRoleType.js +1 -1
- package/{migrations → src/migrations}/110700_transferState.js +1 -1
- package/{migrations → src/migrations}/110900_settlementState.js +1 -1
- package/{migrations → src/migrations}/112000_bulkTransferState.js +1 -1
- package/{migrations → src/migrations}/112100_bulkProcessingState.js +1 -1
- package/{migrations → src/migrations}/200100_participant.js +1 -1
- package/{migrations → src/migrations}/200200_participantContact.js +1 -1
- package/{migrations → src/migrations}/200300_participantEndpoint.js +1 -1
- package/{migrations → src/migrations}/200400_participantParty.js +1 -1
- package/{migrations → src/migrations}/200600_token.js +1 -1
- package/{migrations → src/migrations}/200601_token-indexes.js +1 -1
- package/{migrations → src/migrations}/300100_transferDuplicateCheck.js +2 -2
- package/{migrations → src/migrations}/300150_bulkTransferDuplicateCheck.js +2 -2
- package/{migrations → src/migrations}/300200_transfer.js +2 -2
- package/{migrations → src/migrations}/300202_transfer-decimal184.js +1 -1
- package/{migrations → src/migrations}/300250_bulkTransfer.js +2 -3
- package/{migrations → src/migrations}/300275_bulkTransferAssociation.js +2 -3
- package/{migrations → src/migrations}/300300_ilpPacket.js +1 -1
- package/{migrations → src/migrations}/300400_transferStateChange.js +1 -1
- package/{migrations → src/migrations}/300450_bulkTransferStateChange.js +1 -1
- package/{migrations → src/migrations}/300500_segment.js +1 -1
- package/{migrations → src/migrations}/310100_participantCurrency.js +1 -1
- package/{migrations → src/migrations}/310200_transferParticipant.js +1 -1
- package/{migrations → src/migrations}/310202_transferParticipant-decimal184.js +1 -1
- package/{migrations → src/migrations}/310204_transferParticipant-participantId.js +2 -2
- package/{migrations → src/migrations}/310300_participantPosition.js +1 -1
- package/{migrations → src/migrations}/310302_participantPosition-decimal184.js +1 -1
- package/{migrations → src/migrations}/310400_participantPositionChange.js +1 -1
- package/{migrations → src/migrations}/310402_participantPositionChange-decimal184.js +1 -1
- package/{migrations → src/migrations}/310403_participantPositionChange-participantCurrencyId.js +2 -2
- package/{migrations → src/migrations}/310404_participantPositionChange-change.js +2 -2
- package/{migrations → src/migrations}/310500_participantLimit.js +1 -1
- package/{migrations → src/migrations}/310502_participantLimit-decimal184.js +1 -1
- package/{migrations → src/migrations}/400100_settlementWindow.js +1 -1
- package/{migrations → src/migrations}/400200_settlement.js +1 -1
- package/{migrations → src/migrations}/400300_settlementSettlementWindow.js +1 -1
- package/{migrations → src/migrations}/400301_settlementSettlementWindow-indexes.js +0 -1
- package/{migrations → src/migrations}/400400_settlementWindowStateChange.js +1 -1
- package/{migrations → src/migrations}/400500_settlementTransferParticipant.js +1 -1
- package/{migrations → src/migrations}/400502_settlementTransferParticipant-decimal184.js +1 -1
- package/{migrations → src/migrations}/400600_settlementParticipantCurrency.js +1 -1
- package/{migrations → src/migrations}/400602_settlementParticipantCurrency-decimal184.js +1 -1
- package/{migrations → src/migrations}/400700_settlementParticipantCurrencyStateChange.js +1 -1
- package/{migrations → src/migrations}/400800_settlementStateChange.js +1 -1
- package/{migrations → src/migrations}/400900_settlementWindowContent.js +1 -1
- package/{migrations → src/migrations}/401000_settlementWindowContentStateChange.js +1 -1
- package/{migrations → src/migrations}/401001_settlementWindowContentStateChange-indexes.js +6 -6
- package/{migrations → src/migrations}/401200_settlementContentAggregation.js +1 -1
- package/{migrations → src/migrations}/401300_settlementModel.js +1 -1
- package/{migrations → src/migrations}/410100_transferFulfilmentDuplicateCheck.js +1 -1
- package/{migrations → src/migrations}/410102_transferFulfilmentDuplicateCheck-dropForeignTransferId.js +1 -1
- package/{migrations → src/migrations}/410103_transferFulfilmentDuplicateCheck-hashNullable.js +1 -1
- package/{migrations → src/migrations}/410200_transferFulfilment.js +1 -1
- package/{migrations → src/migrations}/410202_transferFulfilment-ilpFulfilment.js +1 -1
- package/{migrations → src/migrations}/410203_transferFulfilment-foreignTransferFulfilmentId.js +1 -1
- package/{migrations → src/migrations}/410240_bulkTransferFulfilmentDuplicateCheck.js +1 -1
- package/{migrations → src/migrations}/410250_bulkTransferFulfilment.js +1 -1
- package/{migrations → src/migrations}/410300_transferExtension.js +1 -1
- package/{migrations → src/migrations}/410302_transferExtension-transferErrorId.js +1 -1
- package/{migrations → src/migrations}/410350_bulkTransferExtension.js +1 -1
- package/{migrations → src/migrations}/410400_transferTimeout.js +1 -1
- package/{migrations → src/migrations}/410450_transferErrorDuplicateCheck.js +1 -1
- package/{migrations → src/migrations}/410500_transferError.js +1 -1
- package/{migrations → src/migrations}/410502_transferError-foreignTransferErrorDuplicateCheckId.js +1 -1
- package/{migrations → src/migrations}/410550_bulkTransferError.js +1 -1
- package/{migrations → src/migrations}/410600_expiringTransfer.js +1 -1
- package/{migrations → src/migrations}/500401_quote-hotfix-2719.js +8 -8
- package/{migrations → src/migrations}/500501_feature-fixSubIdRef.js +12 -12
- package/{migrations → src/migrations}/500601_party-2480.js +3 -3
- package/{migrations → src/migrations}/501001_quoteExtension-quote-service-174.js +1 -2
- package/{migrations → src/migrations}/501002_quoteExtension-2522.js +3 -3
- package/{migrations → src/migrations}/600010_fxTransferType.js +1 -1
- package/{migrations → src/migrations}/600012_fxParticipantCurrencyType.js +1 -1
- package/{migrations → src/migrations}/600100_fxTransferDuplicateCheck.js +2 -2
- package/{migrations → src/migrations}/600110_fxTransferErrorDuplicateCheck.js.js +1 -1
- package/{migrations → src/migrations}/600200_fxTransfer.js +2 -2
- package/{migrations → src/migrations}/600400_fxTransferStateChange.js +1 -1
- package/{migrations → src/migrations}/600501_fxWatchList.js +2 -2
- package/{migrations → src/migrations}/600600_fxTransferFulfilmentDuplicateCheck.js +1 -1
- package/{migrations → src/migrations}/600700_fxTransferFulfilment.js +1 -1
- package/{migrations → src/migrations}/600800_fxTransferExtension.js +1 -1
- package/{migrations → src/migrations}/601400_fxTransferTimeout.js +1 -1
- package/{migrations → src/migrations}/601500_fxTransferError.js +1 -1
- package/{migrations → src/migrations}/610200_fxTransferParticipant.js +1 -1
- package/{migrations → src/migrations}/610202_fxTransferParticipant-participantId.js +2 -2
- package/{migrations → src/migrations}/610403_participantPositionChange-fxTransfer.js +1 -1
- package/{migrations → src/migrations}/800100_quotePartyView.js +1 -1
- package/{migrations → src/migrations}/800101_feature-fixSubIdRef.js +1 -1
- package/{migrations → src/migrations}/800200_quoteView.js +1 -1
- package/{migrations → src/migrations}/800300_quoteResponseView.js +1 -1
- package/{migrations → src/migrations}/900100_foreign-keys.js +18 -18
- package/{migrations → src/migrations}/900101_foreign-keys.js +6 -6
- package/{migrations → src/migrations}/910100_feature904DDL.js +7 -7
- package/{migrations → src/migrations}/910101_feature904DataMigration.js +1 -1
- package/{migrations → src/migrations}/910102_feature949DataMigration.js +1 -1
- package/{migrations → src/migrations}/910103_feature1093SettlementByCurrency.js +3 -3
- package/{migrations → src/migrations}/940101_quotePartyIdInfoExtension-2522.js +25 -25
- package/{migrations → src/migrations}/950101_transferParticipantStateChange.js +2 -2
- package/{migrations → src/migrations}/950102_settlementModel-adjustPosition.js +2 -2
- package/{migrations → src/migrations}/950103_dropTransferParticipantStateChange.js +3 -3
- package/{migrations → src/migrations}/950104_settlementModel-settlementAccountTypeId.js +3 -3
- package/src/migrations/950107_settlementWindowContent_foreign_settlementModel.js +63 -0
- package/{migrations → src/migrations}/950108_participantProxy.js +1 -2
- package/{migrations → src/migrations}/950120_fxQuoteConversionTerms_sourceAmount_nullable.js +1 -1
- package/{migrations → src/migrations}/960100_create_externalParticipant.js +2 -2
- package/{migrations → src/migrations}/960110_alter_transferParticipant__addFiled_externalParticipantId.js +2 -2
- package/{migrations → src/migrations}/961001_transferForwarded.js +1 -1
- package/{migrations → src/migrations}/961002_fxTransferForwarded.js +1 -1
- package/src/models/participant/externalParticipant.int.ts +85 -0
- package/src/models/participant/facade.js +4 -2
- package/src/models/participant/participantCurrencyCached.js +1 -1
- package/src/models/position/facade.js +8 -2
- package/src/models/transfer/facade.int.ts +139 -0
- package/src/models/transfer/facade.js +8 -3
- package/src/models/transfer/transferDuplicateCheck.js +2 -2
- package/src/models/transfer/transferError.int.ts +112 -0
- package/src/models/transfer/transferExtension.int.ts +137 -0
- package/src/models/transfer/transferStateChange.int.ts +117 -0
- package/{seeds → src/seeds}/participant.js +1 -1
- package/{seeds → src/seeds}/settlementInterchange.js +1 -0
- package/src/settlement/api/handlerRoutes.js +71 -0
- package/src/settlement/api/handlers/health.js +10 -0
- package/src/settlement/api/handlers/index.js +57 -0
- package/src/settlement/api/handlers/settlementWindows/{id}.js +103 -0
- package/src/settlement/api/handlers/settlementWindows.js +77 -0
- package/src/settlement/api/handlers/settlements/{id}.js +133 -0
- package/src/settlement/api/handlers/settlements/{sid}/participants/{pid}/accounts/{aid}.js +127 -0
- package/src/settlement/api/handlers/settlements/{sid}/participants/{pid}.js +127 -0
- package/src/settlement/api/handlers/settlements.js +114 -0
- package/src/settlement/api/openapiRouting.js +87 -0
- package/src/settlement/api/routes.js +176 -0
- package/src/settlement/domain/rules/index.js +46 -0
- package/src/settlement/domain/settlement/index.js +405 -0
- package/src/settlement/domain/settlementWindow/index.js +117 -0
- package/src/settlement/domain/transactions/index.js +83 -0
- package/src/settlement/domain/transferSettlement/index.js +57 -0
- package/src/settlement/handlers/deferredSettlement/handler.js +180 -0
- package/src/settlement/handlers/grossSettlement/handler.js +180 -0
- package/src/settlement/handlers/index.js +101 -0
- package/src/settlement/handlers/register.js +92 -0
- package/src/settlement/handlers/rules/handler.js +164 -0
- package/src/settlement/interface/swagger-handler.json +34 -0
- package/src/settlement/interface/swagger.json +1560 -0
- package/src/settlement/lib/db.js +32 -0
- package/src/settlement/lib/kafka/index.js +41 -0
- package/src/settlement/lib/kafka/producer.js +142 -0
- package/src/settlement/lib/scriptEngine.js +99 -0
- package/src/settlement/lib/scriptsLoader.js +175 -0
- package/src/settlement/lib/utility.js +243 -0
- package/src/settlement/models/ilpPackets/ilpPacket.js +42 -0
- package/src/settlement/models/lib/enums.js +192 -0
- package/src/settlement/models/misc/migrationLock.js +53 -0
- package/src/settlement/models/settlement/facade.js +1652 -0
- package/src/settlement/models/settlement/index.js +55 -0
- package/src/settlement/models/settlement/participantCurrency.js +48 -0
- package/src/settlement/models/settlement/settlement.js +49 -0
- package/src/settlement/models/settlement/settlementModel.js +44 -0
- package/src/settlement/models/settlement/settlementParticipantCurrency.js +61 -0
- package/src/settlement/models/settlement/settlementStateChange.js +44 -0
- package/src/settlement/models/settlement/settlementTransferParticipant.js +46 -0
- package/src/settlement/models/settlementWindow/facade.js +345 -0
- package/src/settlement/models/settlementWindow/index.js +47 -0
- package/src/settlement/models/settlementWindow/settlementWindowStateChange.js +55 -0
- package/src/settlement/models/settlementWindowContent/facade.js +79 -0
- package/src/settlement/models/settlementWindowContent/index.js +40 -0
- package/src/settlement/models/settlementWindowContent/settlementWindowContentStateChange.js +53 -0
- package/src/settlement/models/transferSettlement/facade.js +363 -0
- package/src/settlement/models/transferSettlement/index.js +42 -0
- package/src/settlement/shared/logger/index.js +7 -0
- package/src/settlement/shared/plugins.js +88 -0
- package/src/settlement/shared/setup.js +224 -0
- package/src/settlement/utils/truthyProperty.js +37 -0
- package/src/shared/legacyUtilShim.js +20 -0
- package/src/shared/plugins.js +3 -3
- package/src/shared/results.ts +22 -0
- package/src/shared/results.unit.ts +38 -0
- package/src/shared/setup.js +14 -1
- package/src/testing/api-helpers.ts +1222 -0
- package/src/testing/exec-async.ts +67 -0
- package/src/testing/harness.snapshot.sql +3895 -0
- package/src/testing/harness.test.ts +15 -0
- package/src/testing/harness.ts +1160 -0
- package/src/testing/kafka.ts +221 -0
- package/src/testing/prng.ts +82 -0
- package/src/testing/rdkafka.test.ts +263 -0
- package/src/testing/run.ts +559 -0
- package/src/testing/snapshot.test.ts +92 -0
- package/src/testing/snapshot.ts +549 -0
- package/src/testing/tap-stream.ts +164 -0
- package/src/testing/types.ts +95 -0
- package/src/testing/util.ts +333 -0
- package/src/types/central-services-error-handling.d.ts +72 -0
- package/src/types/central-services-stream.d.ts +148 -0
- package/test-integration.Dockerfile +0 -2
- package/test.Dockerfile +0 -2
- package/tsconfig.json +40 -0
- package/config/knexfile.js +0 -19
- package/migrations/950107_settlementWindowContent_foreign_settlementModel.js +0 -63
- package/src/api/index.js +0 -16
- package/src/lib/config.js +0 -81
- /package/{migrations → src/migrations}/110101_contactType-indexes.js +0 -0
- /package/{migrations → src/migrations}/110301_endpointType-indexes.js +0 -0
- /package/{migrations → src/migrations}/110401_ledgerEntryType-indexes.js +0 -0
- /package/{migrations → src/migrations}/110451_ledgerAccountType-indexes.js +0 -0
- /package/{migrations → src/migrations}/110501_participantLimitType-indexes.js +0 -0
- /package/{migrations → src/migrations}/110601_transferParticipantRoleType-indexes.js +0 -0
- /package/{migrations → src/migrations}/110800_settlementWindowState.js +0 -0
- /package/{migrations → src/migrations}/111000_amountType.js +0 -0
- /package/{migrations → src/migrations}/111001_amountType-indexes.js +0 -0
- /package/{migrations → src/migrations}/111100_balanceOfPayments.js +0 -0
- /package/{migrations → src/migrations}/111101_balanceOfPayments-indexes.js +0 -0
- /package/{migrations → src/migrations}/111200_partyIdentifierType.js +0 -0
- /package/{migrations → src/migrations}/111201_partyIdentifierType-indexes.js +0 -0
- /package/{migrations → src/migrations}/111300_partyType.js +0 -0
- /package/{migrations → src/migrations}/111301_partyType-indexes.js +0 -0
- /package/{migrations → src/migrations}/111400_quoteDuplicateCheck.js +0 -0
- /package/{migrations → src/migrations}/111500_transactionInitiator.js +0 -0
- /package/{migrations → src/migrations}/111501_transactionInitiator-indexes.js +0 -0
- /package/{migrations → src/migrations}/111600_transactionInitiatorType.js +0 -0
- /package/{migrations → src/migrations}/111601_transactionInitiatorType-indexes.js +0 -0
- /package/{migrations → src/migrations}/111700_settlementDelay.js +0 -0
- /package/{migrations → src/migrations}/111701_settlementDelay-indexes.js +0 -0
- /package/{migrations → src/migrations}/111800_settlementInterchange.js +0 -0
- /package/{migrations → src/migrations}/111801_settlementInterchange-indexes.js +0 -0
- /package/{migrations → src/migrations}/111900_settlementGranularity.js +0 -0
- /package/{migrations → src/migrations}/111901_settlementGranularity-indexes.js +0 -0
- /package/{migrations → src/migrations}/112101_bulkProcessingState-indexes.js +0 -0
- /package/{migrations → src/migrations}/200101_participant-indexes.js +0 -0
- /package/{migrations → src/migrations}/200201_participantContact-indexes.js +0 -0
- /package/{migrations → src/migrations}/200301_participantEndpoint-indexes.js +0 -0
- /package/{migrations → src/migrations}/200401_participantParty-indexes.js +0 -0
- /package/{migrations → src/migrations}/300201_transfer-indexes.js +0 -0
- /package/{migrations → src/migrations}/300251_bulkTransfer-indexes.js +0 -0
- /package/{migrations → src/migrations}/300276_bulkTransferAssociation-indexes.js +0 -0
- /package/{migrations → src/migrations}/300401_transferStateChange-indexes.js +0 -0
- /package/{migrations → src/migrations}/300451_bulkTransferStateChange-indexes.js +0 -0
- /package/{migrations → src/migrations}/300501_segment-indexes.js +0 -0
- /package/{migrations → src/migrations}/310101_participantCurrency-indexes.js +0 -0
- /package/{migrations → src/migrations}/310201_transferParticipant-indexes.js +0 -0
- /package/{migrations → src/migrations}/310203_transferParticipant-indexes.js +0 -0
- /package/{migrations → src/migrations}/310301_participantPosition-indexes.js +0 -0
- /package/{migrations → src/migrations}/310401_participantPositionChange-indexes.js +0 -0
- /package/{migrations → src/migrations}/310405_participantPositionChange-positionChange.js +0 -0
- /package/{migrations → src/migrations}/310406_participantPositionChange-positionChange-revert.js +0 -0
- /package/{migrations → src/migrations}/310501_participantLimit-indexes.js +0 -0
- /package/{migrations → src/migrations}/310503_participantLimit-indexes-composite.js +0 -0
- /package/{migrations → src/migrations}/400401_settlmentWindowStateChange-indexes.js +0 -0
- /package/{migrations → src/migrations}/400501_settlementTransferParticipant-indexes.js +0 -0
- /package/{migrations → src/migrations}/400601_settlementParticipantCurrency-indexes.js +0 -0
- /package/{migrations → src/migrations}/400701_settlementParticipantCurrencyStateChange-indexes.js +0 -0
- /package/{migrations → src/migrations}/400801_settlementStateChange-indexes.js +0 -0
- /package/{migrations → src/migrations}/401002_settlementWindowContent-indexes.js +0 -0
- /package/{migrations → src/migrations}/401201_settlementContentAggregation-indexes.js +0 -0
- /package/{migrations → src/migrations}/401301_settlementModel-indexes.js +0 -0
- /package/{migrations → src/migrations}/410101_transferFulfilmentDuplicateCheck-indexes.js +0 -0
- /package/{migrations → src/migrations}/410201_transferFulfilment-indexes.js +0 -0
- /package/{migrations → src/migrations}/410301_transferExtension-indexes.js +0 -0
- /package/{migrations → src/migrations}/410351_bulkTransferExtension-indexes.js +0 -0
- /package/{migrations → src/migrations}/410401_transferTimeout-indexes.js +0 -0
- /package/{migrations → src/migrations}/410501_transferError-indexes.js +0 -0
- /package/{migrations → src/migrations}/410551_bulkTransferError-indexes.js +0 -0
- /package/{migrations → src/migrations}/410601_expiringTransfer-indexes.js +0 -0
- /package/{migrations → src/migrations}/500100_transactionReference.js +0 -0
- /package/{migrations → src/migrations}/500101_transactionReference-indexes.js +0 -0
- /package/{migrations → src/migrations}/500200_transactionScenario.js +0 -0
- /package/{migrations → src/migrations}/500201_transactionScenario-indexes.js +0 -0
- /package/{migrations → src/migrations}/500300_transactionSubScenario.js +0 -0
- /package/{migrations → src/migrations}/500400_quote.js +0 -0
- /package/{migrations → src/migrations}/500500_quoteParty.js +0 -0
- /package/{migrations → src/migrations}/500600_party.js +0 -0
- /package/{migrations → src/migrations}/500700_quoteResponse.js +0 -0
- /package/{migrations → src/migrations}/500800_quoteResponseIlpPacket.js +0 -0
- /package/{migrations → src/migrations}/500900_geoCode.js +0 -0
- /package/{migrations → src/migrations}/501000_quoteExtension.js +0 -0
- /package/{migrations → src/migrations}/501100_quoteResponseDuplicateCheck.js +0 -0
- /package/{migrations → src/migrations}/501200_quoteError.js +0 -0
- /package/{migrations → src/migrations}/501300_transferRules.js +0 -0
- /package/{migrations → src/migrations}/600011_fxTransferType-indexes.js +0 -0
- /package/{migrations → src/migrations}/600013_fxParticipantCurrencyType-indexes.js +0 -0
- /package/{migrations → src/migrations}/600201_fxTransfer-indexes.js +0 -0
- /package/{migrations → src/migrations}/600401_fxTransferStateChange-indexes.js +0 -0
- /package/{migrations → src/migrations}/600502_fxWatchList-indexes.js +0 -0
- /package/{migrations → src/migrations}/600601_fxTransferFulfilmentDuplicateCheck-indexes.js +0 -0
- /package/{migrations → src/migrations}/600701_fxTransferFulfilment-indexes.js +0 -0
- /package/{migrations → src/migrations}/601401_fxTransferTimeout-indexes.js +0 -0
- /package/{migrations → src/migrations}/601501_fxTransferError-indexes.js +0 -0
- /package/{migrations → src/migrations}/610201_fxTransferParticipant-indexes.js +0 -0
- /package/{migrations → src/migrations}/910102_hotfix954.js +0 -0
- /package/{migrations → src/migrations}/940100_quotePartyIdInfoExtension.js +0 -0
- /package/{migrations → src/migrations}/950100_settlementContentAggregation-decimal184.js +0 -0
- /package/{migrations → src/migrations}/950106_unique_settlement_model_ledger_account_currency.js +0 -0
- /package/{migrations → src/migrations}/950109_fxQuote.js +0 -0
- /package/{migrations → src/migrations}/950110_fxQuoteResponse.js +0 -0
- /package/{migrations → src/migrations}/950111_fxQuoteError.js +0 -0
- /package/{migrations → src/migrations}/950113_fxQuoteDuplicateCheck.js +0 -0
- /package/{migrations → src/migrations}/950114_fxQuoteResponseDuplicateCheck.js +0 -0
- /package/{migrations → src/migrations}/950115_fxQuoteConversionTerms.js +0 -0
- /package/{migrations → src/migrations}/950116_fxQuoteConversionTermsExtension.js +0 -0
- /package/{migrations → src/migrations}/950117_fxQuoteResponseConversionTerms.js +0 -0
- /package/{migrations → src/migrations}/950118_fxQuoteResponseConversionTermsExtension.js +0 -0
- /package/{migrations → src/migrations}/950119_fxCharge.js +0 -0
- /package/{migrations → src/migrations}/960111_alter_fxTransferParticipant__addFiled_externalParticipantId.js +0 -0
- /package/{migrations → src/migrations}/960112_fxTransfer-indexes2.js +0 -0
- /package/{migrations → src/migrations}/960113_fxTransferExtension-indexes.js +0 -0
- /package/{migrations → src/migrations}/960114_fxTransferTimeout-indexes2.js +0 -0
- /package/{migrations → src/migrations}/961000_participantEndpoint_unique.js +0 -0
- /package/{migrations → src/migrations}/migration.template +0 -0
- /package/{seeds → src/seeds}/amountType.js +0 -0
- /package/{seeds → src/seeds}/balanceOfPayments.js +0 -0
- /package/{seeds → src/seeds}/bulkProcessingState.js +0 -0
- /package/{seeds → src/seeds}/bulkTransferState.js +0 -0
- /package/{seeds → src/seeds}/currency.js +0 -0
- /package/{seeds → src/seeds}/endpointType.js +0 -0
- /package/{seeds → src/seeds}/fxParticipantCurrencyType.js +0 -0
- /package/{seeds → src/seeds}/fxTransferType.js +0 -0
- /package/{seeds → src/seeds}/ledgerAccountType.js +0 -0
- /package/{seeds → src/seeds}/ledgerEntryType.js +0 -0
- /package/{seeds → src/seeds}/participantLimitType.js +0 -0
- /package/{seeds → src/seeds}/partyIdentifierType.js +0 -0
- /package/{seeds → src/seeds}/partyType.js +0 -0
- /package/{seeds → src/seeds}/settlementDelay.js +0 -0
- /package/{seeds → src/seeds}/settlementGranularity.js +0 -0
- /package/{seeds → src/seeds}/settlementState.js +0 -0
- /package/{seeds → src/seeds}/settlementWindow1State.js +0 -0
- /package/{seeds → src/seeds}/settlementWindow2Open.js +0 -0
- /package/{seeds → src/seeds}/transactionInitiator.js +0 -0
- /package/{seeds → src/seeds}/transactionInitiatorType.js +0 -0
- /package/{seeds → src/seeds}/transactionScenario.js +0 -0
- /package/{seeds → src/seeds}/transferParticipantRoleType.js +0 -0
- /package/{seeds → src/seeds}/transferState.js +0 -0
- /package/{seeds → src/seeds}/z1000_settlementModel-deprecated.js- +0 -0
|
@@ -0,0 +1,559 @@
|
|
|
1
|
+
import assert from 'node:assert'
|
|
2
|
+
import { spawn, spawnSync } from 'node:child_process'
|
|
3
|
+
import path from 'node:path'
|
|
4
|
+
import process from 'node:process'
|
|
5
|
+
import test, { run } from "node:test"
|
|
6
|
+
import { tap, spec } from 'node:test/reporters'
|
|
7
|
+
import Harness from './harness'
|
|
8
|
+
import { mergeTapStreams } from './tap-stream'
|
|
9
|
+
import { ResultTest, RunTask, RunTaskCoverage, RunTaskIntegration, RunTaskUnit, TagTask } from './types'
|
|
10
|
+
import { convertToXunit, findFiles } from './util'
|
|
11
|
+
import { finished, pipeline } from 'node:stream/promises'
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* @file run.ts
|
|
15
|
+
* @description Single entrypoint for running unit tests, coverage checks, integration tests.
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
export const PROJECT_ROOT = path.resolve(__dirname, '../..')
|
|
19
|
+
|
|
20
|
+
// Local binaries.
|
|
21
|
+
export const NYC_BIN = path.join(PROJECT_ROOT, 'node_modules/.bin/nyc')
|
|
22
|
+
export const TAPE_BIN = path.join(PROJECT_ROOT, 'node_modules/.bin/tape')
|
|
23
|
+
export const TAP_XUNIT_BIN = path.join(PROJECT_ROOT, 'node_modules/.bin/tap-xunit')
|
|
24
|
+
|
|
25
|
+
/**
|
|
26
|
+
* @function exitWhenStdoutFlushed
|
|
27
|
+
* @description Exit the process only once everything already queued on stdout has actually been
|
|
28
|
+
* written. `process.exit()` is synchronous, but writes to a non-TTY stdout (e.g. when piped into
|
|
29
|
+
* `tap-spec`) are not - calling it right after a large `console.log`/`write` can truncate that
|
|
30
|
+
* write mid-flight. Queuing an empty write and exiting in its callback guarantees everything
|
|
31
|
+
* enqueued before it has already drained, since a writable stream processes writes in order.
|
|
32
|
+
*/
|
|
33
|
+
function exitWhenStdoutFlushed(code: number): void {
|
|
34
|
+
process.stdout.write('', () => process.exit(code))
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
async function main() {
|
|
38
|
+
try {
|
|
39
|
+
const task = parseOptions(process.argv.slice(2), process.env)
|
|
40
|
+
switch (task.tag) {
|
|
41
|
+
case 'TEST_UNIT': {
|
|
42
|
+
const result = await runUnitTests(task)
|
|
43
|
+
exitWhenStdoutFlushed(result.exitCode)
|
|
44
|
+
break
|
|
45
|
+
}
|
|
46
|
+
case 'TEST_COVERAGE': {
|
|
47
|
+
await runCoverage(task)
|
|
48
|
+
if (task.onlyReport) {
|
|
49
|
+
exitWhenStdoutFlushed(0)
|
|
50
|
+
}
|
|
51
|
+
return
|
|
52
|
+
}
|
|
53
|
+
case 'TEST_INTEGRATION': {
|
|
54
|
+
const result = await runIntegrationTests(task)
|
|
55
|
+
exitWhenStdoutFlushed(result.exitCode)
|
|
56
|
+
break
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
} catch (err: any) {
|
|
60
|
+
console.log('Error:', err.message)
|
|
61
|
+
console.log(usage)
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
/**
|
|
66
|
+
* @function runUnitTests
|
|
67
|
+
* @description Run the unit tests based on the RunTaskUnit settings.
|
|
68
|
+
*/
|
|
69
|
+
async function runUnitTests(task: RunTaskUnit): Promise<ResultTest> {
|
|
70
|
+
let results: ResultTest
|
|
71
|
+
switch (task.type) {
|
|
72
|
+
case 'TAPE':
|
|
73
|
+
console.error('==== Running Legacy (Tape) unit tests ====')
|
|
74
|
+
results = await runUnitTestsTape()
|
|
75
|
+
break
|
|
76
|
+
case 'NATIVE':
|
|
77
|
+
console.error('==== Running New (Native) unit tests ====')
|
|
78
|
+
results = await runUnitTestsNative()
|
|
79
|
+
break
|
|
80
|
+
case 'BOTH': {
|
|
81
|
+
// Run both suites silently (only accumulating their output, not relaying it live) because
|
|
82
|
+
// each one emits its own separate "TAP version 13" document. Concatenating two raw TAP
|
|
83
|
+
// documents on stdout is not valid TAP, and Node's native-test TAP dialect (nested
|
|
84
|
+
// subtests, large stack-trace diagnostics) crashes older TAP consumers like tap-spec
|
|
85
|
+
// outright - which then throws EPIPE back into this process when it keeps writing to a
|
|
86
|
+
// closed pipe. mergeTapStreams() below produces the one valid, flattened TAP document
|
|
87
|
+
// that should actually reach stdout.
|
|
88
|
+
console.error('==== Running Legacy (Tape) unit tests ====')
|
|
89
|
+
const resultsTape = await runUnitTestsTape({ silent: true })
|
|
90
|
+
assert(resultsTape.exitCode !== null, 'Encountered unknown error when runUnitTestsTape().')
|
|
91
|
+
console.error('==== Running New (Native) unit tests ====')
|
|
92
|
+
const resultsNative = await runUnitTestsNative({ silent: true })
|
|
93
|
+
assert(resultsNative.exitCode !== null, 'Encountered unknown error when runUnitTestsNative().')
|
|
94
|
+
|
|
95
|
+
const outputMerged = mergeTapStreams(resultsTape.output, resultsNative.output)
|
|
96
|
+
const exitCodeMerged = [resultsTape, resultsNative].reduce((acc, result) => {
|
|
97
|
+
assert(result.exitCode !== null)
|
|
98
|
+
return acc > 0 ? acc : result.exitCode
|
|
99
|
+
}, 0)
|
|
100
|
+
|
|
101
|
+
console.log(outputMerged)
|
|
102
|
+
|
|
103
|
+
results = {
|
|
104
|
+
output: outputMerged,
|
|
105
|
+
exitCode: exitCodeMerged
|
|
106
|
+
}
|
|
107
|
+
break
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
if (task.output === 'XUNIT') {
|
|
112
|
+
assert(task.outputPath, 'expected outputPath to be defined')
|
|
113
|
+
|
|
114
|
+
// Export to xunit.
|
|
115
|
+
await convertToXunit(results.output, task.outputPath)
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
return results
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* @function runCoverage
|
|
123
|
+
* @description Run the unit tests while collecting coverage, and produce the coverage report.
|
|
124
|
+
* See: https://github.com/istanbuljs/nyc#combining-reports-from-multiple-runs to understand the
|
|
125
|
+
* approach here.
|
|
126
|
+
*/
|
|
127
|
+
async function runCoverage(task: RunTaskCoverage): Promise<void> {
|
|
128
|
+
switch (task.type) {
|
|
129
|
+
case 'TAPE':
|
|
130
|
+
runCoverageTape({ silent: false, noClean: false })
|
|
131
|
+
break
|
|
132
|
+
case 'NATIVE':
|
|
133
|
+
runCoverageNative({ silent: false, noClean: false })
|
|
134
|
+
break
|
|
135
|
+
case 'BOTH':
|
|
136
|
+
// First run native check, but don't cleanup so we accumulate coverage between runs.
|
|
137
|
+
runCoverageTape({ silent: true, noClean: false })
|
|
138
|
+
runCoverageNative({ silent: true, noClean: true })
|
|
139
|
+
// Generate combined report.
|
|
140
|
+
spawnSync(NYC_BIN, ['report', '--reporter=lcov', '--reporter=text-summary'], {
|
|
141
|
+
cwd: PROJECT_ROOT,
|
|
142
|
+
stdio: 'inherit'
|
|
143
|
+
})
|
|
144
|
+
break
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
// Check coverage thresholds unless --only-report was specified.
|
|
148
|
+
if (!task.onlyReport) {
|
|
149
|
+
const checkResult = spawnSync(NYC_BIN, ['check-coverage'], {
|
|
150
|
+
cwd: PROJECT_ROOT,
|
|
151
|
+
stdio: 'inherit'
|
|
152
|
+
})
|
|
153
|
+
if (checkResult.status !== 0) {
|
|
154
|
+
process.exit(checkResult.status ?? 1)
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
type NycOptions = {
|
|
160
|
+
silent: boolean
|
|
161
|
+
noClean: boolean
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
/**
|
|
165
|
+
* @function runCoverageTape
|
|
166
|
+
* @description Run legacy tape tests under nyc coverage.
|
|
167
|
+
*/
|
|
168
|
+
function runCoverageTape(opts: NycOptions): void {
|
|
169
|
+
const testFiles = findFiles(
|
|
170
|
+
path.join(PROJECT_ROOT, 'test/unit'),
|
|
171
|
+
'**/*.test.js'
|
|
172
|
+
).map(file => path.join(PROJECT_ROOT, 'test/unit', file))
|
|
173
|
+
|
|
174
|
+
if (testFiles.length === 0) {
|
|
175
|
+
console.warn(`runCoverageTape() - no test files found.`)
|
|
176
|
+
return
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
const nycArgs: string[] = []
|
|
180
|
+
if (opts.silent) nycArgs.push('--silent')
|
|
181
|
+
if (opts.noClean) nycArgs.push('--no-clean')
|
|
182
|
+
if (!opts.silent) nycArgs.push('--reporter=lcov', '--reporter=text-summary')
|
|
183
|
+
|
|
184
|
+
const args = [...nycArgs, '--', TAPE_BIN, ...testFiles]
|
|
185
|
+
const result = spawnSync(NYC_BIN, args, {
|
|
186
|
+
cwd: PROJECT_ROOT,
|
|
187
|
+
stdio: 'inherit',
|
|
188
|
+
env: {
|
|
189
|
+
...process.env,
|
|
190
|
+
NODE_OPTIONS: '-r ts-node/register'
|
|
191
|
+
}
|
|
192
|
+
})
|
|
193
|
+
|
|
194
|
+
if (result.error) {
|
|
195
|
+
console.error('Failed to run tape tests with coverage:', result.error.message)
|
|
196
|
+
process.exit(1)
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
/**
|
|
201
|
+
* @function runCoverageNative
|
|
202
|
+
* @description Run native Node.js tests under nyc coverage.
|
|
203
|
+
*/
|
|
204
|
+
function runCoverageNative(opts: NycOptions): void {
|
|
205
|
+
const testFiles = findFiles(
|
|
206
|
+
path.join(PROJECT_ROOT, 'src'),
|
|
207
|
+
'**/*.unit.ts'
|
|
208
|
+
).map(f => path.join(PROJECT_ROOT, 'src', f))
|
|
209
|
+
|
|
210
|
+
if (testFiles.length === 0) {
|
|
211
|
+
console.warn(`runCoverageNative() - no test files found.`)
|
|
212
|
+
return
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
const nycArgs: string[] = []
|
|
216
|
+
if (opts.silent) nycArgs.push('--silent')
|
|
217
|
+
if (opts.noClean) nycArgs.push('--no-clean')
|
|
218
|
+
if (!opts.silent) nycArgs.push('--reporter=lcov', '--reporter=text-summary')
|
|
219
|
+
|
|
220
|
+
const args = [
|
|
221
|
+
...nycArgs,
|
|
222
|
+
'--',
|
|
223
|
+
process.execPath,
|
|
224
|
+
'--require', 'ts-node/register',
|
|
225
|
+
'--test',
|
|
226
|
+
'--test-reporter=tap',
|
|
227
|
+
...testFiles
|
|
228
|
+
]
|
|
229
|
+
const result = spawnSync(NYC_BIN, args, {
|
|
230
|
+
cwd: PROJECT_ROOT,
|
|
231
|
+
stdio: 'inherit',
|
|
232
|
+
env: process.env
|
|
233
|
+
})
|
|
234
|
+
|
|
235
|
+
if (result.error) {
|
|
236
|
+
console.error('Failed to run native tests with coverage:', result.error.message)
|
|
237
|
+
process.exit(1)
|
|
238
|
+
}
|
|
239
|
+
}
|
|
240
|
+
|
|
241
|
+
/**
|
|
242
|
+
* @function runUnitTestsTape
|
|
243
|
+
* @description Run the legacy unit tests written with tape.
|
|
244
|
+
*/
|
|
245
|
+
async function runUnitTestsTape(opts: { silent?: boolean } = {}): Promise<ResultTest> {
|
|
246
|
+
return new Promise((resolve) => {
|
|
247
|
+
const testFiles = findFiles(
|
|
248
|
+
path.join(PROJECT_ROOT, 'test/unit'),
|
|
249
|
+
'**/*.test.js'
|
|
250
|
+
)
|
|
251
|
+
.map(file => path.join(PROJECT_ROOT, 'test/unit', file))
|
|
252
|
+
|
|
253
|
+
|
|
254
|
+
if (testFiles.length === 0) {
|
|
255
|
+
console.warn(`runUnitTestsTape() - no test files found.`)
|
|
256
|
+
resolve({ output: '', exitCode: 0 })
|
|
257
|
+
return
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
// Run node directly with tape module to allow debugging.
|
|
261
|
+
const tapeEntry = path.join(PROJECT_ROOT, 'node_modules/tape/bin/tape')
|
|
262
|
+
const proc = spawn(process.execPath, [
|
|
263
|
+
'-r', 'ts-node/register',
|
|
264
|
+
'--inspect',
|
|
265
|
+
tapeEntry,
|
|
266
|
+
...testFiles
|
|
267
|
+
], {
|
|
268
|
+
cwd: PROJECT_ROOT,
|
|
269
|
+
env: {
|
|
270
|
+
...process.env,
|
|
271
|
+
NODE_OPTIONS: '-r ts-node/register'
|
|
272
|
+
},
|
|
273
|
+
stdio: ['inherit', 'pipe', 'pipe']
|
|
274
|
+
})
|
|
275
|
+
|
|
276
|
+
let output = ''
|
|
277
|
+
proc.stdout.on('data', (data: Buffer) => {
|
|
278
|
+
const chunk = data.toString()
|
|
279
|
+
output += chunk
|
|
280
|
+
if (!opts.silent) process.stdout.write(chunk)
|
|
281
|
+
})
|
|
282
|
+
|
|
283
|
+
proc.stderr.on('data', (data: Buffer) => {
|
|
284
|
+
process.stderr.write(data)
|
|
285
|
+
})
|
|
286
|
+
|
|
287
|
+
proc.on('close', (code) => {
|
|
288
|
+
resolve({ output, exitCode: code })
|
|
289
|
+
})
|
|
290
|
+
|
|
291
|
+
proc.on('error', (err) => {
|
|
292
|
+
console.error('Failed to run legacy tests:', err.message)
|
|
293
|
+
resolve({ output: '', exitCode: 1 })
|
|
294
|
+
})
|
|
295
|
+
})
|
|
296
|
+
}
|
|
297
|
+
|
|
298
|
+
/**
|
|
299
|
+
* @function runUnitTestsNative
|
|
300
|
+
* @description Run the unit tests with the native nodejs test suite.
|
|
301
|
+
*/
|
|
302
|
+
async function runUnitTestsNative(opts: { silent?: boolean } = {}): Promise<ResultTest> {
|
|
303
|
+
return new Promise((resolve) => {
|
|
304
|
+
const testFiles = findFiles(
|
|
305
|
+
path.join(PROJECT_ROOT, 'src'),
|
|
306
|
+
'**/*.unit.ts'
|
|
307
|
+
).map(f => path.join(PROJECT_ROOT, 'src', f))
|
|
308
|
+
|
|
309
|
+
if (testFiles.length === 0) {
|
|
310
|
+
resolve({ output: '', exitCode: 0 })
|
|
311
|
+
return
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
const proc = spawn(process.execPath, [
|
|
315
|
+
'--require', 'ts-node/register',
|
|
316
|
+
'--test',
|
|
317
|
+
'--test-reporter=tap',
|
|
318
|
+
...testFiles
|
|
319
|
+
], {
|
|
320
|
+
cwd: PROJECT_ROOT,
|
|
321
|
+
env: process.env,
|
|
322
|
+
stdio: ['inherit', 'pipe', 'pipe']
|
|
323
|
+
})
|
|
324
|
+
|
|
325
|
+
let output = ''
|
|
326
|
+
proc.stdout.on('data', (data: Buffer) => {
|
|
327
|
+
const chunk = data.toString()
|
|
328
|
+
output += chunk
|
|
329
|
+
if (!opts.silent) process.stdout.write(chunk)
|
|
330
|
+
})
|
|
331
|
+
|
|
332
|
+
proc.stderr.on('data', (data: Buffer) => {
|
|
333
|
+
process.stderr.write(data)
|
|
334
|
+
})
|
|
335
|
+
|
|
336
|
+
proc.on('close', (code) => {
|
|
337
|
+
resolve({ output, exitCode: code })
|
|
338
|
+
})
|
|
339
|
+
|
|
340
|
+
proc.on('error', (err) => {
|
|
341
|
+
console.error('Failed to run native tests:', err.message)
|
|
342
|
+
resolve({ output: '', exitCode: 1 })
|
|
343
|
+
})
|
|
344
|
+
})
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
/**
|
|
348
|
+
* @function runIntegrationTests
|
|
349
|
+
* @description Runs the integration tests with the native nodejs test suite.
|
|
350
|
+
*/
|
|
351
|
+
async function runIntegrationTests(task: RunTaskIntegration): Promise<ResultTest> {
|
|
352
|
+
const files = findFiles(
|
|
353
|
+
path.join(PROJECT_ROOT, 'src'),
|
|
354
|
+
'**/*.int.ts'
|
|
355
|
+
).map(f => path.join(PROJECT_ROOT, 'src', f))
|
|
356
|
+
|
|
357
|
+
if (files.length === 0) {
|
|
358
|
+
return { output: '', exitCode: 0 }
|
|
359
|
+
}
|
|
360
|
+
|
|
361
|
+
let exitCode = 0
|
|
362
|
+
|
|
363
|
+
process.once('uncaughtException', async (err) => {
|
|
364
|
+
console.error(`Uncaught exception:`, err)
|
|
365
|
+
process.exit(1)
|
|
366
|
+
})
|
|
367
|
+
|
|
368
|
+
process.once('unhandledRejection', async (err) => {
|
|
369
|
+
console.error(`Unhandled rejection:`, err)
|
|
370
|
+
process.exit(1)
|
|
371
|
+
})
|
|
372
|
+
|
|
373
|
+
const testStream = run({
|
|
374
|
+
files,
|
|
375
|
+
// Run each test file in a separate process.
|
|
376
|
+
isolation: 'process',
|
|
377
|
+
// Tweak this depending on what resources we have.
|
|
378
|
+
concurrency: 2,
|
|
379
|
+
})
|
|
380
|
+
.on('test:fail', () => {
|
|
381
|
+
exitCode = 1
|
|
382
|
+
})
|
|
383
|
+
|
|
384
|
+
const tapStream = testStream.compose(spec)
|
|
385
|
+
tapStream.pipe(process.stdout)
|
|
386
|
+
await finished(testStream)
|
|
387
|
+
|
|
388
|
+
// TODO: figure out how to export to xml to be compatible with circleci.
|
|
389
|
+
|
|
390
|
+
return {
|
|
391
|
+
output: '',
|
|
392
|
+
exitCode
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
|
|
396
|
+
const parseUnitTestOptions = (args: Array<string>): Omit<RunTaskUnit, 'tag'> => {
|
|
397
|
+
let type = 'BOTH' as RunTaskUnit['type']
|
|
398
|
+
let output = 'DEFAULT' as RunTaskUnit['output']
|
|
399
|
+
let outputPath = undefined
|
|
400
|
+
args.forEach(arg => {
|
|
401
|
+
const matchType = arg.match(/--type=(.*)$/)
|
|
402
|
+
if (matchType) {
|
|
403
|
+
assert(matchType.length >= 2)
|
|
404
|
+
switch (matchType[1]) {
|
|
405
|
+
case 'tape': type = 'TAPE'; return
|
|
406
|
+
case 'native': type = 'NATIVE'; return
|
|
407
|
+
case 'both': type = 'BOTH'; return
|
|
408
|
+
default: {
|
|
409
|
+
throw new Error(`Invalid --type=${matchType[1]}, expected: tape | native | both`)
|
|
410
|
+
}
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
const matchOutput = arg.match(/^--output=(.*)$/)
|
|
415
|
+
if (matchOutput) {
|
|
416
|
+
assert(matchOutput.length >= 2)
|
|
417
|
+
switch (matchOutput[1]) {
|
|
418
|
+
case 'default': output = 'DEFAULT'; return
|
|
419
|
+
case 'xunit': output = 'XUNIT'; return
|
|
420
|
+
default: {
|
|
421
|
+
throw new Error(`Invalid --output=${matchOutput[1]}, expected: default | xunit`)
|
|
422
|
+
}
|
|
423
|
+
}
|
|
424
|
+
}
|
|
425
|
+
|
|
426
|
+
const matchOutputPath = arg.match(/^--outputPath=(.*)$/)
|
|
427
|
+
if (matchOutputPath) {
|
|
428
|
+
assert(matchOutputPath.length >= 2)
|
|
429
|
+
outputPath = matchOutputPath[1]
|
|
430
|
+
assert(typeof outputPath === 'string')
|
|
431
|
+
return
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
throw new Error(`unhandled arg: ${arg}`)
|
|
435
|
+
})
|
|
436
|
+
|
|
437
|
+
// Validate options.
|
|
438
|
+
if (output === 'XUNIT' && !outputPath) {
|
|
439
|
+
throw new Error('Validation error:\n Required: `--outputPath` when `--output=xunit`.')
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
return { type, output, outputPath }
|
|
443
|
+
}
|
|
444
|
+
|
|
445
|
+
const parseCoverageOptions = (args: Array<string>): Omit<RunTaskCoverage, 'tag'> => {
|
|
446
|
+
let type = 'BOTH' as RunTaskUnit['type']
|
|
447
|
+
let onlyReport = false
|
|
448
|
+
args.forEach(arg => {
|
|
449
|
+
const matchType = arg.match(/--type=(.*)$/)
|
|
450
|
+
if (matchType) {
|
|
451
|
+
assert(matchType.length >= 2)
|
|
452
|
+
switch (matchType[1]) {
|
|
453
|
+
case 'tape': type = 'TAPE'; return
|
|
454
|
+
case 'native': type = 'NATIVE'; return
|
|
455
|
+
case 'both': type = 'BOTH'; return
|
|
456
|
+
default: {
|
|
457
|
+
throw new Error(`Invalid --type=${matchType[1]}, expected: tape | native | both .`)
|
|
458
|
+
}
|
|
459
|
+
}
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
if (arg.match(/^--only-report$/)) {
|
|
463
|
+
onlyReport = true
|
|
464
|
+
return
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
throw new Error(`unhandled arg: ${arg}. Supported args for coverage are:\n --type=[tape|native|both]\n --only-report .`)
|
|
468
|
+
})
|
|
469
|
+
|
|
470
|
+
return {
|
|
471
|
+
type,
|
|
472
|
+
onlyReport
|
|
473
|
+
}
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
const parseIntegrationOptions = (args: Array<string>): Omit<RunTaskIntegration, 'tag'> => {
|
|
477
|
+
return {
|
|
478
|
+
|
|
479
|
+
}
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
function parseOptions(args: Array<string>, _env: NodeJS.ProcessEnv): RunTask {
|
|
483
|
+
assert(args.length > 0, 'expected at least one arg.')
|
|
484
|
+
const taskCommand = args.shift()
|
|
485
|
+
let tag: TagTask
|
|
486
|
+
|
|
487
|
+
switch (taskCommand) {
|
|
488
|
+
case 'unit': {
|
|
489
|
+
tag = 'TEST_UNIT'
|
|
490
|
+
const options = parseUnitTestOptions(args)
|
|
491
|
+
|
|
492
|
+
return {
|
|
493
|
+
tag,
|
|
494
|
+
...options,
|
|
495
|
+
}
|
|
496
|
+
}
|
|
497
|
+
case 'coverage': {
|
|
498
|
+
tag = 'TEST_COVERAGE'
|
|
499
|
+
const options = parseCoverageOptions(args)
|
|
500
|
+
|
|
501
|
+
return {
|
|
502
|
+
tag,
|
|
503
|
+
...options
|
|
504
|
+
}
|
|
505
|
+
}
|
|
506
|
+
case 'integration': {
|
|
507
|
+
tag = 'TEST_INTEGRATION'
|
|
508
|
+
const options = parseIntegrationOptions(args)
|
|
509
|
+
|
|
510
|
+
return {
|
|
511
|
+
tag,
|
|
512
|
+
...options
|
|
513
|
+
}
|
|
514
|
+
}
|
|
515
|
+
case 'functional': {
|
|
516
|
+
throw new Error(`'${taskCommand}' not implemented.`)
|
|
517
|
+
}
|
|
518
|
+
default: {
|
|
519
|
+
throw new Error(`'${taskCommand}' not found.`)
|
|
520
|
+
}
|
|
521
|
+
}
|
|
522
|
+
}
|
|
523
|
+
|
|
524
|
+
const usage = `
|
|
525
|
+
Usage:
|
|
526
|
+
|
|
527
|
+
./testing/run.ts [unit | coverage | integration | functional]\n\n\
|
|
528
|
+
'unit' : Run the unit tests.
|
|
529
|
+
'coverage' : Run the unit tests then check coverage.
|
|
530
|
+
'integration' : Run the integration tests.
|
|
531
|
+
'functional' : *Preview - not yet implemented* Run the functional tests.
|
|
532
|
+
|
|
533
|
+
|
|
534
|
+
Examples:
|
|
535
|
+
|
|
536
|
+
# Run the unit tests.
|
|
537
|
+
./testing/run.ts unit
|
|
538
|
+
|
|
539
|
+
# Run only the the legacy tape tests.
|
|
540
|
+
./testing/run.ts unit --type=tape
|
|
541
|
+
|
|
542
|
+
# Run all the tests, outputting xunit
|
|
543
|
+
./testing/run.ts unit --output=xunit
|
|
544
|
+
|
|
545
|
+
# Run the unit tests then check for coverage (will exit != 0 if it fails.)
|
|
546
|
+
./testing/run.ts coverage
|
|
547
|
+
|
|
548
|
+
# Run coverage report only (don't check thresholds)
|
|
549
|
+
./testing/run.ts coverage --only-report
|
|
550
|
+
|
|
551
|
+
# Run all of the integration tests.
|
|
552
|
+
./testing/run.ts integration
|
|
553
|
+
|
|
554
|
+
`
|
|
555
|
+
|
|
556
|
+
main().catch((error) => {
|
|
557
|
+
console.error(error)
|
|
558
|
+
process.exit(1)
|
|
559
|
+
})
|
|
@@ -0,0 +1,92 @@
|
|
|
1
|
+
import { describe, it } from "node:test";
|
|
2
|
+
import { Snapshot, SnapshotRange } from "./snapshot";
|
|
3
|
+
import assert from "node:assert";
|
|
4
|
+
|
|
5
|
+
/**
|
|
6
|
+
* This is an example test for how the snapshot testing library works.
|
|
7
|
+
*/
|
|
8
|
+
describe('snapshot smoke test', () => {
|
|
9
|
+
it('updates the snapshot', () => {
|
|
10
|
+
const result = {
|
|
11
|
+
a: true,
|
|
12
|
+
b: {
|
|
13
|
+
icecream: 'yummy21'
|
|
14
|
+
},
|
|
15
|
+
c: new Date()
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
Snapshot.from(`{
|
|
19
|
+
"a": true,
|
|
20
|
+
"b": {
|
|
21
|
+
"icecream": "yummy21"
|
|
22
|
+
},
|
|
23
|
+
"c": ":ignore"
|
|
24
|
+
}`).checkStringUnwrap(JSON.stringify(result, null, 2))
|
|
25
|
+
})
|
|
26
|
+
})
|
|
27
|
+
|
|
28
|
+
describe('replaceSnapshot()', () => {
|
|
29
|
+
it('replaces the old snapshot with the new', () => {
|
|
30
|
+
const contents = '\n\nSnapshot.from(\`{\n "a": true,\n "c": ":ignore"\n }\n `).checkStringUnwrap(JSON.stringify(result, null, 2))'
|
|
31
|
+
const range = Snapshot._snapshotRange(contents, 3)
|
|
32
|
+
const newSnapshot = '\`{\n "a": true,\n "c": ":ignore"\n}\n`'
|
|
33
|
+
const expected = '\n\nSnapshot.from(\`{\n "a": true,\n "c": ":ignore"\n }\n `).checkStringUnwrap(JSON.stringify(result, null, 2))'
|
|
34
|
+
const actual = Snapshot._replaceSnapshot(contents, range, newSnapshot)
|
|
35
|
+
|
|
36
|
+
assert.equal(actual, expected)
|
|
37
|
+
})
|
|
38
|
+
})
|
|
39
|
+
|
|
40
|
+
describe('snapshotRange()', () => {
|
|
41
|
+
it('snapshotRange() gets the range inbetween ``', () => {
|
|
42
|
+
check('\n`thing`\n', 2, {start: 2, end: 8, indent: 0})
|
|
43
|
+
|
|
44
|
+
check('aaa`thingbbb`ccc', 1, {start: 4, end: 13, indent: 0})
|
|
45
|
+
checkSplit('aaa`thingbbb`ccc', 1, ['aaa', '`thingbbb`', 'ccc'])
|
|
46
|
+
|
|
47
|
+
check('\nblabla\n `{\n "a": true,\n "b": {\n "icecream": "yummy"\n },\n "c": ":ignore"\n }\n `', 3, {start: 15, end: 116, indent: 4} )
|
|
48
|
+
checkSplit(
|
|
49
|
+
'\nblabla\n `{\n "a": true,\n "b": {\n "icecream": "yummy"\n },\n "c": ":ignore"\n }\n `',
|
|
50
|
+
3,
|
|
51
|
+
[
|
|
52
|
+
'\nblabla\n ',
|
|
53
|
+
'`{\n "a": true,\n "b": {\n "icecream": "yummy"\n },\n "c": ":ignore"\n }\n `',
|
|
54
|
+
'',
|
|
55
|
+
]
|
|
56
|
+
)
|
|
57
|
+
|
|
58
|
+
check(
|
|
59
|
+
`Snapshot.from(\`{
|
|
60
|
+
"a": true,
|
|
61
|
+
"b": {
|
|
62
|
+
"icecream": "yummy"
|
|
63
|
+
},
|
|
64
|
+
"c": ":ignore"
|
|
65
|
+
}\`).checkStringUnwrap(JSON.stringify(result, null, 2))`
|
|
66
|
+
, 1, {start: 15, end: 111, indent: 4})
|
|
67
|
+
|
|
68
|
+
check(
|
|
69
|
+
`Snapshot.from(\`{
|
|
70
|
+
"a": true,
|
|
71
|
+
"c": ":ignore"
|
|
72
|
+
}
|
|
73
|
+
\`).checkStringUnwrap(JSON.stringify(result, null, 2))`
|
|
74
|
+
, 1, {start: 15, end: 66, indent: 4})
|
|
75
|
+
})
|
|
76
|
+
|
|
77
|
+
const check = (input: string, startLine: number, expected: SnapshotRange) => {
|
|
78
|
+
const result = Snapshot._snapshotRange(input, startLine)
|
|
79
|
+
assert.deepEqual(result, expected)
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
const checkSplit = (input: string, startLine: number, expect: [string, string, string]) => {
|
|
83
|
+
const result = Snapshot._snapshotRange(input, startLine)
|
|
84
|
+
const head = input.slice(0, result.start - 1)
|
|
85
|
+
const body = input.slice(result.start - 1, result.end)
|
|
86
|
+
const tail = input.slice(result.end)
|
|
87
|
+
|
|
88
|
+
assert.equal(head, expect[0])
|
|
89
|
+
assert.equal(body, expect[1])
|
|
90
|
+
assert.equal(tail, expect[2])
|
|
91
|
+
}
|
|
92
|
+
})
|