@fluid-experimental/tree 2.0.0-rc.2.0.1 → 2.0.0-rc.3.0.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/CHANGELOG.md +23 -0
- package/api-report/experimental-tree.api.md +2 -2
- package/dist/ChangeCompression.d.ts +2 -2
- package/dist/ChangeCompression.d.ts.map +1 -1
- package/dist/ChangeCompression.js +1 -1
- package/dist/ChangeCompression.js.map +1 -1
- package/dist/ChangeTypes.d.ts +1 -1
- package/dist/ChangeTypes.d.ts.map +1 -1
- package/dist/ChangeTypes.js +4 -4
- package/dist/ChangeTypes.js.map +1 -1
- package/dist/Checkout.d.ts +3 -3
- package/dist/Checkout.d.ts.map +1 -1
- package/dist/Checkout.js +17 -17
- package/dist/Checkout.js.map +1 -1
- package/dist/EditLog.d.ts +1 -1
- package/dist/EditLog.d.ts.map +1 -1
- package/dist/EditLog.js +9 -9
- package/dist/EditLog.js.map +1 -1
- package/dist/EditUtilities.d.ts +3 -3
- package/dist/EditUtilities.d.ts.map +1 -1
- package/dist/EditUtilities.js +6 -6
- package/dist/EditUtilities.js.map +1 -1
- package/dist/Forest.d.ts.map +1 -1
- package/dist/Forest.js +23 -23
- package/dist/Forest.js.map +1 -1
- package/dist/HistoryEditFactory.d.ts +1 -1
- package/dist/HistoryEditFactory.d.ts.map +1 -1
- package/dist/HistoryEditFactory.js +7 -7
- package/dist/HistoryEditFactory.js.map +1 -1
- package/dist/IdConversion.d.ts.map +1 -1
- package/dist/IdConversion.js.map +1 -1
- package/dist/LogViewer.d.ts +2 -2
- package/dist/LogViewer.d.ts.map +1 -1
- package/dist/LogViewer.js +7 -7
- package/dist/LogViewer.js.map +1 -1
- package/dist/MergeHealth.d.ts.map +1 -1
- package/dist/MergeHealth.js +1 -1
- package/dist/MergeHealth.js.map +1 -1
- package/dist/NodeIdUtilities.d.ts +1 -1
- package/dist/NodeIdUtilities.d.ts.map +1 -1
- package/dist/NodeIdUtilities.js +1 -1
- package/dist/NodeIdUtilities.js.map +1 -1
- package/dist/PayloadUtilities.d.ts.map +1 -1
- package/dist/PayloadUtilities.js +2 -2
- package/dist/PayloadUtilities.js.map +1 -1
- package/dist/ReconciliationPath.d.ts +1 -1
- package/dist/ReconciliationPath.d.ts.map +1 -1
- package/dist/ReconciliationPath.js.map +1 -1
- package/dist/RevisionValueCache.d.ts.map +1 -1
- package/dist/RevisionValueCache.js +2 -2
- package/dist/RevisionValueCache.js.map +1 -1
- package/dist/RevisionView.d.ts +2 -2
- package/dist/RevisionView.d.ts.map +1 -1
- package/dist/RevisionView.js.map +1 -1
- package/dist/SerializationUtilities.d.ts +1 -1
- package/dist/SerializationUtilities.d.ts.map +1 -1
- package/dist/SerializationUtilities.js.map +1 -1
- package/dist/SharedTree.d.ts +8 -7
- package/dist/SharedTree.d.ts.map +1 -1
- package/dist/SharedTree.js +78 -78
- package/dist/SharedTree.js.map +1 -1
- package/dist/SharedTreeEncoder.d.ts +1 -1
- package/dist/SharedTreeEncoder.d.ts.map +1 -1
- package/dist/SharedTreeEncoder.js +31 -31
- package/dist/SharedTreeEncoder.js.map +1 -1
- package/dist/Summary.d.ts +2 -2
- package/dist/Summary.d.ts.map +1 -1
- package/dist/Summary.js +2 -2
- package/dist/Summary.js.map +1 -1
- package/dist/SummaryBackCompatibility.d.ts.map +1 -1
- package/dist/SummaryBackCompatibility.js.map +1 -1
- package/dist/SummaryTestUtilities.d.ts +1 -1
- package/dist/SummaryTestUtilities.d.ts.map +1 -1
- package/dist/SummaryTestUtilities.js.map +1 -1
- package/dist/Transaction.d.ts +3 -3
- package/dist/Transaction.d.ts.map +1 -1
- package/dist/Transaction.js +3 -3
- package/dist/Transaction.js.map +1 -1
- package/dist/TransactionInternal.d.ts +3 -3
- package/dist/TransactionInternal.d.ts.map +1 -1
- package/dist/TransactionInternal.js +6 -6
- package/dist/TransactionInternal.js.map +1 -1
- package/dist/TreeCompressor.d.ts +5 -1
- package/dist/TreeCompressor.d.ts.map +1 -1
- package/dist/TreeCompressor.js +5 -5
- package/dist/TreeCompressor.js.map +1 -1
- package/dist/TreeNodeHandle.d.ts +1 -1
- package/dist/TreeNodeHandle.d.ts.map +1 -1
- package/dist/TreeNodeHandle.js.map +1 -1
- package/dist/TreeView.d.ts +1 -1
- package/dist/TreeView.d.ts.map +1 -1
- package/dist/TreeView.js +2 -3
- package/dist/TreeView.js.map +1 -1
- package/dist/UuidUtilities.d.ts.map +1 -1
- package/dist/UuidUtilities.js.map +1 -1
- package/dist/id-compressor/AppendOnlySortedMap.d.ts.map +1 -1
- package/dist/id-compressor/AppendOnlySortedMap.js +3 -3
- package/dist/id-compressor/AppendOnlySortedMap.js.map +1 -1
- package/dist/id-compressor/IdCompressor.d.ts +1 -1
- package/dist/id-compressor/IdCompressor.d.ts.map +1 -1
- package/dist/id-compressor/IdCompressor.js +25 -26
- package/dist/id-compressor/IdCompressor.js.map +1 -1
- package/dist/id-compressor/IdRange.d.ts.map +1 -1
- package/dist/id-compressor/IdRange.js +2 -2
- package/dist/id-compressor/IdRange.js.map +1 -1
- package/dist/id-compressor/NumericUuid.d.ts.map +1 -1
- package/dist/id-compressor/NumericUuid.js +2 -1
- package/dist/id-compressor/NumericUuid.js.map +1 -1
- package/dist/id-compressor/SessionIdNormalizer.d.ts.map +1 -1
- package/dist/id-compressor/SessionIdNormalizer.js +8 -9
- package/dist/id-compressor/SessionIdNormalizer.js.map +1 -1
- package/dist/migration-shim/migrationDeltaHandler.d.ts +1 -1
- package/dist/migration-shim/migrationDeltaHandler.d.ts.map +1 -1
- package/dist/migration-shim/migrationDeltaHandler.js +11 -11
- package/dist/migration-shim/migrationDeltaHandler.js.map +1 -1
- package/dist/migration-shim/migrationShim.d.ts +8 -4
- package/dist/migration-shim/migrationShim.d.ts.map +1 -1
- package/dist/migration-shim/migrationShim.js +13 -13
- package/dist/migration-shim/migrationShim.js.map +1 -1
- package/dist/migration-shim/migrationShimFactory.d.ts +2 -2
- package/dist/migration-shim/migrationShimFactory.d.ts.map +1 -1
- package/dist/migration-shim/migrationShimFactory.js +2 -2
- package/dist/migration-shim/migrationShimFactory.js.map +1 -1
- package/dist/migration-shim/packageVersion.d.ts +0 -2
- package/dist/migration-shim/packageVersion.d.ts.map +1 -1
- package/dist/migration-shim/packageVersion.js +0 -2
- package/dist/migration-shim/packageVersion.js.map +1 -1
- package/dist/migration-shim/sharedTreeDeltaHandler.d.ts.map +1 -1
- package/dist/migration-shim/sharedTreeDeltaHandler.js +8 -8
- package/dist/migration-shim/sharedTreeDeltaHandler.js.map +1 -1
- package/dist/migration-shim/sharedTreeShim.d.ts +2 -2
- package/dist/migration-shim/sharedTreeShim.d.ts.map +1 -1
- package/dist/migration-shim/sharedTreeShim.js +8 -4
- package/dist/migration-shim/sharedTreeShim.js.map +1 -1
- package/dist/migration-shim/sharedTreeShimFactory.d.ts +1 -1
- package/dist/migration-shim/sharedTreeShimFactory.d.ts.map +1 -1
- package/dist/migration-shim/sharedTreeShimFactory.js +2 -2
- package/dist/migration-shim/sharedTreeShimFactory.js.map +1 -1
- package/dist/migration-shim/shimChannelServices.d.ts +1 -1
- package/dist/migration-shim/shimChannelServices.d.ts.map +1 -1
- package/dist/migration-shim/shimChannelServices.js.map +1 -1
- package/dist/migration-shim/shimDeltaConnection.d.ts +1 -1
- package/dist/migration-shim/shimDeltaConnection.d.ts.map +1 -1
- package/dist/migration-shim/shimDeltaConnection.js +2 -2
- package/dist/migration-shim/shimDeltaConnection.js.map +1 -1
- package/dist/migration-shim/shimHandle.d.ts.map +1 -1
- package/dist/migration-shim/shimHandle.js.map +1 -1
- package/dist/migration-shim/types.d.ts +1 -1
- package/dist/migration-shim/types.d.ts.map +1 -1
- package/dist/migration-shim/types.js.map +1 -1
- package/dist/migration-shim/utils.d.ts +1 -1
- package/dist/migration-shim/utils.d.ts.map +1 -1
- package/dist/migration-shim/utils.js.map +1 -1
- package/dist/persisted-types/0.0.2.d.ts +1 -1
- package/dist/persisted-types/0.0.2.d.ts.map +1 -1
- package/dist/persisted-types/0.0.2.js.map +1 -1
- package/dist/persisted-types/0.1.1.d.ts +1 -1
- package/dist/persisted-types/0.1.1.d.ts.map +1 -1
- package/dist/persisted-types/0.1.1.js +3 -3
- package/dist/persisted-types/0.1.1.js.map +1 -1
- package/lib/ChangeCompression.d.ts +2 -2
- package/lib/ChangeCompression.d.ts.map +1 -1
- package/lib/ChangeCompression.js +1 -1
- package/lib/ChangeCompression.js.map +1 -1
- package/lib/ChangeTypes.d.ts +1 -1
- package/lib/ChangeTypes.d.ts.map +1 -1
- package/lib/ChangeTypes.js +2 -2
- package/lib/ChangeTypes.js.map +1 -1
- package/lib/Checkout.d.ts +3 -3
- package/lib/Checkout.d.ts.map +1 -1
- package/lib/Checkout.js +4 -4
- package/lib/Checkout.js.map +1 -1
- package/lib/EditLog.d.ts +1 -1
- package/lib/EditLog.d.ts.map +1 -1
- package/lib/EditLog.js +2 -2
- package/lib/EditLog.js.map +1 -1
- package/lib/EditUtilities.d.ts +3 -3
- package/lib/EditUtilities.d.ts.map +1 -1
- package/lib/EditUtilities.js +5 -5
- package/lib/EditUtilities.js.map +1 -1
- package/lib/Forest.d.ts.map +1 -1
- package/lib/Forest.js +2 -2
- package/lib/Forest.js.map +1 -1
- package/lib/HistoryEditFactory.d.ts +1 -1
- package/lib/HistoryEditFactory.d.ts.map +1 -1
- package/lib/HistoryEditFactory.js +5 -5
- package/lib/HistoryEditFactory.js.map +1 -1
- package/lib/IdConversion.d.ts.map +1 -1
- package/lib/IdConversion.js.map +1 -1
- package/lib/LogViewer.d.ts +2 -2
- package/lib/LogViewer.d.ts.map +1 -1
- package/lib/LogViewer.js +3 -3
- package/lib/LogViewer.js.map +1 -1
- package/lib/MergeHealth.d.ts.map +1 -1
- package/lib/MergeHealth.js +1 -1
- package/lib/MergeHealth.js.map +1 -1
- package/lib/NodeIdUtilities.d.ts +1 -1
- package/lib/NodeIdUtilities.d.ts.map +1 -1
- package/lib/NodeIdUtilities.js +1 -1
- package/lib/NodeIdUtilities.js.map +1 -1
- package/lib/PayloadUtilities.d.ts.map +1 -1
- package/lib/PayloadUtilities.js +1 -1
- package/lib/PayloadUtilities.js.map +1 -1
- package/lib/ReconciliationPath.d.ts +1 -1
- package/lib/ReconciliationPath.d.ts.map +1 -1
- package/lib/ReconciliationPath.js.map +1 -1
- package/lib/RevisionValueCache.d.ts.map +1 -1
- package/lib/RevisionValueCache.js +2 -2
- package/lib/RevisionValueCache.js.map +1 -1
- package/lib/RevisionView.d.ts +2 -2
- package/lib/RevisionView.d.ts.map +1 -1
- package/lib/RevisionView.js.map +1 -1
- package/lib/SerializationUtilities.d.ts +1 -1
- package/lib/SerializationUtilities.d.ts.map +1 -1
- package/lib/SerializationUtilities.js.map +1 -1
- package/lib/SharedTree.d.ts +8 -7
- package/lib/SharedTree.d.ts.map +1 -1
- package/lib/SharedTree.js +13 -13
- package/lib/SharedTree.js.map +1 -1
- package/lib/SharedTreeEncoder.d.ts +1 -1
- package/lib/SharedTreeEncoder.d.ts.map +1 -1
- package/lib/SharedTreeEncoder.js +5 -5
- package/lib/SharedTreeEncoder.js.map +1 -1
- package/lib/Summary.d.ts +2 -2
- package/lib/Summary.d.ts.map +1 -1
- package/lib/Summary.js +1 -1
- package/lib/Summary.js.map +1 -1
- package/lib/SummaryBackCompatibility.d.ts.map +1 -1
- package/lib/SummaryBackCompatibility.js.map +1 -1
- package/lib/SummaryTestUtilities.d.ts +1 -1
- package/lib/SummaryTestUtilities.d.ts.map +1 -1
- package/lib/SummaryTestUtilities.js.map +1 -1
- package/lib/Transaction.d.ts +3 -3
- package/lib/Transaction.d.ts.map +1 -1
- package/lib/Transaction.js +3 -3
- package/lib/Transaction.js.map +1 -1
- package/lib/TransactionInternal.d.ts +3 -3
- package/lib/TransactionInternal.d.ts.map +1 -1
- package/lib/TransactionInternal.js +3 -3
- package/lib/TransactionInternal.js.map +1 -1
- package/lib/TreeCompressor.d.ts +5 -1
- package/lib/TreeCompressor.d.ts.map +1 -1
- package/lib/TreeCompressor.js +2 -2
- package/lib/TreeCompressor.js.map +1 -1
- package/lib/TreeNodeHandle.d.ts +1 -1
- package/lib/TreeNodeHandle.d.ts.map +1 -1
- package/lib/TreeNodeHandle.js.map +1 -1
- package/lib/TreeView.d.ts +1 -1
- package/lib/TreeView.d.ts.map +1 -1
- package/lib/TreeView.js +1 -2
- package/lib/TreeView.js.map +1 -1
- package/lib/UuidUtilities.d.ts.map +1 -1
- package/lib/UuidUtilities.js +1 -1
- package/lib/UuidUtilities.js.map +1 -1
- package/lib/id-compressor/AppendOnlySortedMap.d.ts.map +1 -1
- package/lib/id-compressor/AppendOnlySortedMap.js +1 -1
- package/lib/id-compressor/AppendOnlySortedMap.js.map +1 -1
- package/lib/id-compressor/IdCompressor.d.ts +1 -1
- package/lib/id-compressor/IdCompressor.d.ts.map +1 -1
- package/lib/id-compressor/IdCompressor.js +4 -5
- package/lib/id-compressor/IdCompressor.js.map +1 -1
- package/lib/id-compressor/IdRange.d.ts.map +1 -1
- package/lib/id-compressor/IdRange.js +1 -1
- package/lib/id-compressor/IdRange.js.map +1 -1
- package/lib/id-compressor/NumericUuid.d.ts.map +1 -1
- package/lib/id-compressor/NumericUuid.js +2 -1
- package/lib/id-compressor/NumericUuid.js.map +1 -1
- package/lib/id-compressor/SessionIdNormalizer.d.ts.map +1 -1
- package/lib/id-compressor/SessionIdNormalizer.js +1 -2
- package/lib/id-compressor/SessionIdNormalizer.js.map +1 -1
- package/lib/migration-shim/migrationDeltaHandler.d.ts +1 -1
- package/lib/migration-shim/migrationDeltaHandler.d.ts.map +1 -1
- package/lib/migration-shim/migrationDeltaHandler.js +1 -1
- package/lib/migration-shim/migrationDeltaHandler.js.map +1 -1
- package/lib/migration-shim/migrationShim.d.ts +8 -4
- package/lib/migration-shim/migrationShim.d.ts.map +1 -1
- package/lib/migration-shim/migrationShim.js +3 -3
- package/lib/migration-shim/migrationShim.js.map +1 -1
- package/lib/migration-shim/migrationShimFactory.d.ts +2 -2
- package/lib/migration-shim/migrationShimFactory.d.ts.map +1 -1
- package/lib/migration-shim/migrationShimFactory.js +1 -1
- package/lib/migration-shim/migrationShimFactory.js.map +1 -1
- package/lib/migration-shim/packageVersion.d.ts +0 -2
- package/lib/migration-shim/packageVersion.d.ts.map +1 -1
- package/lib/migration-shim/packageVersion.js +0 -2
- package/lib/migration-shim/packageVersion.js.map +1 -1
- package/lib/migration-shim/sharedTreeDeltaHandler.d.ts.map +1 -1
- package/lib/migration-shim/sharedTreeDeltaHandler.js +1 -1
- package/lib/migration-shim/sharedTreeDeltaHandler.js.map +1 -1
- package/lib/migration-shim/sharedTreeShim.d.ts +2 -2
- package/lib/migration-shim/sharedTreeShim.d.ts.map +1 -1
- package/lib/migration-shim/sharedTreeShim.js +6 -2
- package/lib/migration-shim/sharedTreeShim.js.map +1 -1
- package/lib/migration-shim/sharedTreeShimFactory.d.ts +1 -1
- package/lib/migration-shim/sharedTreeShimFactory.d.ts.map +1 -1
- package/lib/migration-shim/sharedTreeShimFactory.js +1 -1
- package/lib/migration-shim/sharedTreeShimFactory.js.map +1 -1
- package/lib/migration-shim/shimChannelServices.d.ts +1 -1
- package/lib/migration-shim/shimChannelServices.d.ts.map +1 -1
- package/lib/migration-shim/shimChannelServices.js.map +1 -1
- package/lib/migration-shim/shimDeltaConnection.d.ts +1 -1
- package/lib/migration-shim/shimDeltaConnection.d.ts.map +1 -1
- package/lib/migration-shim/shimDeltaConnection.js +1 -1
- package/lib/migration-shim/shimDeltaConnection.js.map +1 -1
- package/lib/migration-shim/shimHandle.d.ts.map +1 -1
- package/lib/migration-shim/shimHandle.js.map +1 -1
- package/lib/migration-shim/types.d.ts +1 -1
- package/lib/migration-shim/types.d.ts.map +1 -1
- package/lib/migration-shim/types.js.map +1 -1
- package/lib/migration-shim/utils.d.ts +1 -1
- package/lib/migration-shim/utils.d.ts.map +1 -1
- package/lib/migration-shim/utils.js.map +1 -1
- package/lib/persisted-types/0.0.2.d.ts +1 -1
- package/lib/persisted-types/0.0.2.d.ts.map +1 -1
- package/lib/persisted-types/0.0.2.js.map +1 -1
- package/lib/persisted-types/0.1.1.d.ts +1 -1
- package/lib/persisted-types/0.1.1.d.ts.map +1 -1
- package/lib/persisted-types/0.1.1.js +1 -1
- package/lib/persisted-types/0.1.1.js.map +1 -1
- package/package.json +33 -32
- package/src/ChangeCompression.ts +8 -8
- package/src/ChangeTypes.ts +5 -4
- package/src/Checkout.ts +9 -7
- package/src/EditLog.ts +4 -3
- package/src/EditUtilities.ts +9 -8
- package/src/Forest.ts +3 -2
- package/src/HistoryEditFactory.ts +12 -11
- package/src/IdConversion.ts +2 -2
- package/src/LogViewer.ts +5 -4
- package/src/MergeHealth.ts +2 -1
- package/src/NodeIdUtilities.ts +2 -2
- package/src/PayloadUtilities.ts +2 -1
- package/src/ReconciliationPath.ts +1 -1
- package/src/RevisionValueCache.ts +3 -2
- package/src/RevisionView.ts +3 -3
- package/src/SerializationUtilities.ts +1 -1
- package/src/SharedTree.ts +46 -49
- package/src/SharedTreeEncoder.ts +30 -29
- package/src/Summary.ts +5 -3
- package/src/SummaryBackCompatibility.ts +1 -0
- package/src/SummaryTestUtilities.ts +2 -1
- package/src/Transaction.ts +7 -6
- package/src/TransactionInternal.ts +17 -16
- package/src/TreeCompressor.ts +6 -4
- package/src/TreeNodeHandle.ts +2 -2
- package/src/TreeView.ts +3 -3
- package/src/UuidUtilities.ts +2 -1
- package/src/id-compressor/AppendOnlySortedMap.ts +2 -1
- package/src/id-compressor/IdCompressor.ts +18 -17
- package/src/id-compressor/IdRange.ts +2 -1
- package/src/id-compressor/NumericUuid.ts +1 -1
- package/src/id-compressor/SessionIdNormalizer.ts +3 -3
- package/src/migration-shim/migrationDeltaHandler.ts +3 -2
- package/src/migration-shim/migrationShim.ts +14 -10
- package/src/migration-shim/migrationShimFactory.ts +6 -4
- package/src/migration-shim/packageVersion.ts +0 -2
- package/src/migration-shim/sharedTreeDeltaHandler.ts +3 -2
- package/src/migration-shim/sharedTreeShim.ts +7 -5
- package/src/migration-shim/sharedTreeShimFactory.ts +3 -3
- package/src/migration-shim/shimChannelServices.ts +1 -1
- package/src/migration-shim/shimDeltaConnection.ts +3 -2
- package/src/migration-shim/shimHandle.ts +1 -0
- package/src/migration-shim/types.ts +3 -1
- package/src/migration-shim/utils.ts +2 -1
- package/src/persisted-types/0.0.2.ts +2 -2
- package/src/persisted-types/0.1.1.ts +10 -8
- package/dist/tree-alpha.d.ts +0 -2901
- package/dist/tree-beta.d.ts +0 -348
- package/dist/tree-public.d.ts +0 -348
- package/dist/tree-untrimmed.d.ts +0 -3820
- package/lib/test/AppendOnlySortedMap.perf.tests.d.ts +0 -6
- package/lib/test/AppendOnlySortedMap.perf.tests.d.ts.map +0 -1
- package/lib/test/AppendOnlySortedMap.perf.tests.js +0 -49
- package/lib/test/AppendOnlySortedMap.perf.tests.js.map +0 -1
- package/lib/test/AppendOnlySortedMap.tests.d.ts +0 -6
- package/lib/test/AppendOnlySortedMap.tests.d.ts.map +0 -1
- package/lib/test/AppendOnlySortedMap.tests.js +0 -213
- package/lib/test/AppendOnlySortedMap.tests.js.map +0 -1
- package/lib/test/ChangeCompression.tests.d.ts +0 -6
- package/lib/test/ChangeCompression.tests.d.ts.map +0 -1
- package/lib/test/ChangeCompression.tests.js +0 -154
- package/lib/test/ChangeCompression.tests.js.map +0 -1
- package/lib/test/Checkout.tests.d.ts +0 -10
- package/lib/test/Checkout.tests.d.ts.map +0 -1
- package/lib/test/Checkout.tests.js +0 -460
- package/lib/test/Checkout.tests.js.map +0 -1
- package/lib/test/Common.tests.d.ts +0 -6
- package/lib/test/Common.tests.d.ts.map +0 -1
- package/lib/test/Common.tests.js +0 -102
- package/lib/test/Common.tests.js.map +0 -1
- package/lib/test/EagerCheckout.tests.d.ts +0 -6
- package/lib/test/EagerCheckout.tests.d.ts.map +0 -1
- package/lib/test/EagerCheckout.tests.js +0 -20
- package/lib/test/EagerCheckout.tests.js.map +0 -1
- package/lib/test/Edit.tests.d.ts +0 -6
- package/lib/test/Edit.tests.d.ts.map +0 -1
- package/lib/test/Edit.tests.js +0 -60
- package/lib/test/Edit.tests.js.map +0 -1
- package/lib/test/EditLog.perf.tests.d.ts +0 -6
- package/lib/test/EditLog.perf.tests.d.ts.map +0 -1
- package/lib/test/EditLog.perf.tests.js +0 -41
- package/lib/test/EditLog.perf.tests.js.map +0 -1
- package/lib/test/EditLog.tests.d.ts +0 -6
- package/lib/test/EditLog.tests.d.ts.map +0 -1
- package/lib/test/EditLog.tests.js +0 -355
- package/lib/test/EditLog.tests.js.map +0 -1
- package/lib/test/EditUtilities.tests.d.ts +0 -6
- package/lib/test/EditUtilities.tests.d.ts.map +0 -1
- package/lib/test/EditUtilities.tests.js +0 -512
- package/lib/test/EditUtilities.tests.js.map +0 -1
- package/lib/test/Forest.perf.tests.d.ts +0 -6
- package/lib/test/Forest.perf.tests.d.ts.map +0 -1
- package/lib/test/Forest.perf.tests.js +0 -135
- package/lib/test/Forest.perf.tests.js.map +0 -1
- package/lib/test/Forest.tests.d.ts +0 -6
- package/lib/test/Forest.tests.d.ts.map +0 -1
- package/lib/test/Forest.tests.js +0 -213
- package/lib/test/Forest.tests.js.map +0 -1
- package/lib/test/GenericTransaction.tests.d.ts +0 -6
- package/lib/test/GenericTransaction.tests.d.ts.map +0 -1
- package/lib/test/GenericTransaction.tests.js +0 -31
- package/lib/test/GenericTransaction.tests.js.map +0 -1
- package/lib/test/HistoryEditFactory.tests.d.ts +0 -6
- package/lib/test/HistoryEditFactory.tests.d.ts.map +0 -1
- package/lib/test/HistoryEditFactory.tests.js +0 -170
- package/lib/test/HistoryEditFactory.tests.js.map +0 -1
- package/lib/test/IdCompressor.perf.tests.d.ts +0 -6
- package/lib/test/IdCompressor.perf.tests.d.ts.map +0 -1
- package/lib/test/IdCompressor.perf.tests.js +0 -290
- package/lib/test/IdCompressor.perf.tests.js.map +0 -1
- package/lib/test/IdCompressor.tests.d.ts +0 -6
- package/lib/test/IdCompressor.tests.d.ts.map +0 -1
- package/lib/test/IdCompressor.tests.js +0 -1542
- package/lib/test/IdCompressor.tests.js.map +0 -1
- package/lib/test/IdConversion.tests.d.ts +0 -6
- package/lib/test/IdConversion.tests.d.ts.map +0 -1
- package/lib/test/IdConversion.tests.js +0 -36
- package/lib/test/IdConversion.tests.js.map +0 -1
- package/lib/test/LazyCheckout.tests.d.ts +0 -6
- package/lib/test/LazyCheckout.tests.d.ts.map +0 -1
- package/lib/test/LazyCheckout.tests.js +0 -22
- package/lib/test/LazyCheckout.tests.js.map +0 -1
- package/lib/test/LogViewer.tests.d.ts +0 -6
- package/lib/test/LogViewer.tests.d.ts.map +0 -1
- package/lib/test/LogViewer.tests.js +0 -588
- package/lib/test/LogViewer.tests.js.map +0 -1
- package/lib/test/MergeHealthTelemetryHeartbeat.tests.d.ts +0 -6
- package/lib/test/MergeHealthTelemetryHeartbeat.tests.d.ts.map +0 -1
- package/lib/test/MergeHealthTelemetryHeartbeat.tests.js +0 -351
- package/lib/test/MergeHealthTelemetryHeartbeat.tests.js.map +0 -1
- package/lib/test/NumericUuid.perf.tests.d.ts +0 -6
- package/lib/test/NumericUuid.perf.tests.d.ts.map +0 -1
- package/lib/test/NumericUuid.perf.tests.js +0 -68
- package/lib/test/NumericUuid.perf.tests.js.map +0 -1
- package/lib/test/NumericUuid.tests.d.ts +0 -6
- package/lib/test/NumericUuid.tests.d.ts.map +0 -1
- package/lib/test/NumericUuid.tests.js +0 -192
- package/lib/test/NumericUuid.tests.js.map +0 -1
- package/lib/test/RevisionValueCache.tests.d.ts +0 -6
- package/lib/test/RevisionValueCache.tests.d.ts.map +0 -1
- package/lib/test/RevisionValueCache.tests.js +0 -106
- package/lib/test/RevisionValueCache.tests.js.map +0 -1
- package/lib/test/RevisionView.tests.d.ts +0 -6
- package/lib/test/RevisionView.tests.d.ts.map +0 -1
- package/lib/test/RevisionView.tests.js +0 -131
- package/lib/test/RevisionView.tests.js.map +0 -1
- package/lib/test/SessionIdNormalizer.tests.d.ts +0 -6
- package/lib/test/SessionIdNormalizer.tests.d.ts.map +0 -1
- package/lib/test/SessionIdNormalizer.tests.js +0 -377
- package/lib/test/SessionIdNormalizer.tests.js.map +0 -1
- package/lib/test/SharedTree.fuzz.tests.d.ts +0 -6
- package/lib/test/SharedTree.fuzz.tests.d.ts.map +0 -1
- package/lib/test/SharedTree.fuzz.tests.js +0 -9
- package/lib/test/SharedTree.fuzz.tests.js.map +0 -1
- package/lib/test/SharedTree.perf.tests.d.ts +0 -6
- package/lib/test/SharedTree.perf.tests.d.ts.map +0 -1
- package/lib/test/SharedTree.perf.tests.js +0 -39
- package/lib/test/SharedTree.perf.tests.js.map +0 -1
- package/lib/test/SharedTree.tests.d.ts +0 -6
- package/lib/test/SharedTree.tests.d.ts.map +0 -1
- package/lib/test/SharedTree.tests.js +0 -22
- package/lib/test/SharedTree.tests.js.map +0 -1
- package/lib/test/StringInterner.tests.d.ts +0 -6
- package/lib/test/StringInterner.tests.d.ts.map +0 -1
- package/lib/test/StringInterner.tests.js +0 -73
- package/lib/test/StringInterner.tests.js.map +0 -1
- package/lib/test/Summary.tests.d.ts +0 -7
- package/lib/test/Summary.tests.d.ts.map +0 -1
- package/lib/test/Summary.tests.js +0 -386
- package/lib/test/Summary.tests.js.map +0 -1
- package/lib/test/Transaction.tests.d.ts +0 -6
- package/lib/test/Transaction.tests.d.ts.map +0 -1
- package/lib/test/Transaction.tests.js +0 -124
- package/lib/test/Transaction.tests.js.map +0 -1
- package/lib/test/TransactionInternal.tests.d.ts +0 -6
- package/lib/test/TransactionInternal.tests.d.ts.map +0 -1
- package/lib/test/TransactionInternal.tests.js +0 -576
- package/lib/test/TransactionInternal.tests.js.map +0 -1
- package/lib/test/TreeCompression.tests.d.ts +0 -6
- package/lib/test/TreeCompression.tests.d.ts.map +0 -1
- package/lib/test/TreeCompression.tests.js +0 -291
- package/lib/test/TreeCompression.tests.js.map +0 -1
- package/lib/test/TreeView.tests.d.ts +0 -6
- package/lib/test/TreeView.tests.d.ts.map +0 -1
- package/lib/test/TreeView.tests.js +0 -178
- package/lib/test/TreeView.tests.js.map +0 -1
- package/lib/test/UndoRedoHandler.tests.d.ts +0 -6
- package/lib/test/UndoRedoHandler.tests.d.ts.map +0 -1
- package/lib/test/UndoRedoHandler.tests.js +0 -37
- package/lib/test/UndoRedoHandler.tests.js.map +0 -1
- package/lib/test/fuzz/Generators.d.ts +0 -8
- package/lib/test/fuzz/Generators.d.ts.map +0 -1
- package/lib/test/fuzz/Generators.js +0 -345
- package/lib/test/fuzz/Generators.js.map +0 -1
- package/lib/test/fuzz/SharedTreeFuzzTests.d.ts +0 -23
- package/lib/test/fuzz/SharedTreeFuzzTests.d.ts.map +0 -1
- package/lib/test/fuzz/SharedTreeFuzzTests.js +0 -241
- package/lib/test/fuzz/SharedTreeFuzzTests.js.map +0 -1
- package/lib/test/fuzz/Types.d.ts +0 -136
- package/lib/test/fuzz/Types.d.ts.map +0 -1
- package/lib/test/fuzz/Types.js +0 -6
- package/lib/test/fuzz/Types.js.map +0 -1
- package/lib/test/utilities/IdCompressorTestUtilities.d.ts +0 -246
- package/lib/test/utilities/IdCompressorTestUtilities.d.ts.map +0 -1
- package/lib/test/utilities/IdCompressorTestUtilities.js +0 -608
- package/lib/test/utilities/IdCompressorTestUtilities.js.map +0 -1
- package/lib/test/utilities/MockTransaction.d.ts +0 -35
- package/lib/test/utilities/MockTransaction.d.ts.map +0 -1
- package/lib/test/utilities/MockTransaction.js +0 -51
- package/lib/test/utilities/MockTransaction.js.map +0 -1
- package/lib/test/utilities/PendingLocalStateTests.d.ts +0 -12
- package/lib/test/utilities/PendingLocalStateTests.d.ts.map +0 -1
- package/lib/test/utilities/PendingLocalStateTests.js +0 -223
- package/lib/test/utilities/PendingLocalStateTests.js.map +0 -1
- package/lib/test/utilities/SharedTreeTests.d.ts +0 -12
- package/lib/test/utilities/SharedTreeTests.d.ts.map +0 -1
- package/lib/test/utilities/SharedTreeTests.js +0 -949
- package/lib/test/utilities/SharedTreeTests.js.map +0 -1
- package/lib/test/utilities/SharedTreeVersioningTests.d.ts +0 -11
- package/lib/test/utilities/SharedTreeVersioningTests.d.ts.map +0 -1
- package/lib/test/utilities/SharedTreeVersioningTests.js +0 -439
- package/lib/test/utilities/SharedTreeVersioningTests.js.map +0 -1
- package/lib/test/utilities/SummaryLoadPerfTests.d.ts +0 -10
- package/lib/test/utilities/SummaryLoadPerfTests.d.ts.map +0 -1
- package/lib/test/utilities/SummaryLoadPerfTests.js +0 -105
- package/lib/test/utilities/SummaryLoadPerfTests.js.map +0 -1
- package/lib/test/utilities/SummarySizeTests.d.ts +0 -11
- package/lib/test/utilities/SummarySizeTests.d.ts.map +0 -1
- package/lib/test/utilities/SummarySizeTests.js +0 -160
- package/lib/test/utilities/SummarySizeTests.js.map +0 -1
- package/lib/test/utilities/TestCommon.d.ts +0 -13
- package/lib/test/utilities/TestCommon.d.ts.map +0 -1
- package/lib/test/utilities/TestCommon.js +0 -19
- package/lib/test/utilities/TestCommon.js.map +0 -1
- package/lib/test/utilities/TestNode.d.ts +0 -140
- package/lib/test/utilities/TestNode.d.ts.map +0 -1
- package/lib/test/utilities/TestNode.js +0 -282
- package/lib/test/utilities/TestNode.js.map +0 -1
- package/lib/test/utilities/TestSerializer.d.ts +0 -24
- package/lib/test/utilities/TestSerializer.d.ts.map +0 -1
- package/lib/test/utilities/TestSerializer.js +0 -40
- package/lib/test/utilities/TestSerializer.js.map +0 -1
- package/lib/test/utilities/TestUtilities.d.ts +0 -212
- package/lib/test/utilities/TestUtilities.d.ts.map +0 -1
- package/lib/test/utilities/TestUtilities.js +0 -413
- package/lib/test/utilities/TestUtilities.js.map +0 -1
- package/lib/test/utilities/UndoRedoTests.d.ts +0 -32
- package/lib/test/utilities/UndoRedoTests.d.ts.map +0 -1
- package/lib/test/utilities/UndoRedoTests.js +0 -317
- package/lib/test/utilities/UndoRedoTests.js.map +0 -1
- /package/{dist → lib}/tsdoc-metadata.json +0 -0
|
@@ -1,460 +0,0 @@
|
|
|
1
|
-
/*!
|
|
2
|
-
* Copyright (c) Microsoft Corporation and contributors. All rights reserved.
|
|
3
|
-
* Licensed under the MIT License.
|
|
4
|
-
*/
|
|
5
|
-
import { strict as assert } from 'assert';
|
|
6
|
-
import { validateAssertionError } from '@fluidframework/test-runtime-utils';
|
|
7
|
-
import { expect } from 'chai';
|
|
8
|
-
import { setTrait, EditStatus, StableRange, StablePlace, EditValidationResult, SharedTreeEvent, CheckoutEvent, Change, Side, areRevisionViewsSemanticallyEqual, } from '../index.js';
|
|
9
|
-
import { setUpTestSharedTree, setUpTestTree } from './utilities/TestUtilities.js';
|
|
10
|
-
/**
|
|
11
|
-
* Checkout test suite
|
|
12
|
-
*/
|
|
13
|
-
export function checkoutTests(checkoutName, checkoutFactory, additionalTests) {
|
|
14
|
-
async function setUpTestCheckout(optionsArg) {
|
|
15
|
-
const options = { localMode: true, noFailOnError: true, ...optionsArg };
|
|
16
|
-
const { tree } = setUpTestSharedTree(options);
|
|
17
|
-
return { checkout: await checkoutFactory(tree), tree };
|
|
18
|
-
}
|
|
19
|
-
/**
|
|
20
|
-
* Counts the number of times ViewChange occurs while performing `action`.
|
|
21
|
-
* Checks arguments to ViewChange are correct as well.
|
|
22
|
-
* @param action - Action to perform
|
|
23
|
-
* @param options - Options object used to construct the initial SharedTree
|
|
24
|
-
*/
|
|
25
|
-
async function countViewChange(action, options = { localMode: true }) {
|
|
26
|
-
const { checkout, tree } = await setUpTestCheckout(options);
|
|
27
|
-
const simpleTestTree = setUpTestTree(tree);
|
|
28
|
-
await checkout.waitForPendingUpdates();
|
|
29
|
-
let lastView = checkout.currentView;
|
|
30
|
-
const data = { changeCount: 0 };
|
|
31
|
-
checkout.on(CheckoutEvent.ViewChange, (before, after) => {
|
|
32
|
-
expect(after).equals(checkout.currentView);
|
|
33
|
-
expect(before).equals(lastView);
|
|
34
|
-
lastView = after;
|
|
35
|
-
data.changeCount++;
|
|
36
|
-
});
|
|
37
|
-
// Prevent errors from errors (like failed expects) from being hidden.
|
|
38
|
-
const errors = [];
|
|
39
|
-
checkout.on('error', (error) => {
|
|
40
|
-
errors.push(error);
|
|
41
|
-
});
|
|
42
|
-
await action(checkout, simpleTestTree, data);
|
|
43
|
-
expect(errors).deep.equal([]);
|
|
44
|
-
return data.changeCount;
|
|
45
|
-
}
|
|
46
|
-
async function setUpTestTreeCheckout(options) {
|
|
47
|
-
const { checkout, tree } = await setUpTestCheckout(options);
|
|
48
|
-
const testTree = setUpTestTree(tree);
|
|
49
|
-
await checkout.waitForPendingUpdates();
|
|
50
|
-
return { checkout, sharedTree: tree, testTree };
|
|
51
|
-
}
|
|
52
|
-
describe(checkoutName, () => {
|
|
53
|
-
it('can only have one edit open at a time', async () => {
|
|
54
|
-
const { checkout } = await setUpTestCheckout();
|
|
55
|
-
checkout.openEdit();
|
|
56
|
-
assert.throws(() => checkout.openEdit());
|
|
57
|
-
});
|
|
58
|
-
it('can only close an edit if one is open', async () => {
|
|
59
|
-
const { checkout } = await setUpTestCheckout();
|
|
60
|
-
assert.throws(() => checkout.closeEdit());
|
|
61
|
-
});
|
|
62
|
-
it('can only apply changes if an edit is open', async () => {
|
|
63
|
-
const { checkout, testTree } = await setUpTestTreeCheckout();
|
|
64
|
-
assert.throws(() => checkout.applyChanges(Change.delete(StableRange.only(testTree.left))));
|
|
65
|
-
});
|
|
66
|
-
it('cannot abort an edit if no edit is open', async () => {
|
|
67
|
-
const { checkout } = await setUpTestCheckout();
|
|
68
|
-
assert.throws(() => checkout.abortEdit());
|
|
69
|
-
});
|
|
70
|
-
it('can abort valid edits', async () => {
|
|
71
|
-
const { checkout, testTree } = await setUpTestTreeCheckout();
|
|
72
|
-
checkout.openEdit();
|
|
73
|
-
// Is still valid after a valid edit
|
|
74
|
-
checkout.applyChanges(Change.delete(StableRange.only(testTree.left.identifier)));
|
|
75
|
-
expect(checkout.getEditStatus()).equals(EditStatus.Applied);
|
|
76
|
-
checkout.abortEdit();
|
|
77
|
-
// The left node should still be there
|
|
78
|
-
expect(checkout.currentView.getViewNode(testTree.left.identifier).identifier).not.undefined;
|
|
79
|
-
});
|
|
80
|
-
it('can abort invalid edits', async () => {
|
|
81
|
-
const { checkout, testTree } = await setUpTestTreeCheckout();
|
|
82
|
-
checkout.openEdit();
|
|
83
|
-
// Starts as valid
|
|
84
|
-
expect(checkout.getEditStatus()).equals(EditStatus.Applied);
|
|
85
|
-
// Is invalid after an invalid edit
|
|
86
|
-
expect(() => checkout.applyChanges(Change.insertTree(testTree.left, StablePlace.after(testTree.left)))).throws('Locally constructed edits must be well-formed and valid.');
|
|
87
|
-
expect(checkout.getEditStatus()).equals(EditStatus.Invalid);
|
|
88
|
-
checkout.abortEdit();
|
|
89
|
-
// Next edit is unaffected
|
|
90
|
-
checkout.openEdit();
|
|
91
|
-
expect(checkout.getEditStatus()).equals(EditStatus.Applied);
|
|
92
|
-
checkout.closeEdit();
|
|
93
|
-
});
|
|
94
|
-
it('can abort malformed edits', async () => {
|
|
95
|
-
const { checkout, testTree } = await setUpTestTreeCheckout();
|
|
96
|
-
checkout.openEdit();
|
|
97
|
-
// Starts as valid
|
|
98
|
-
expect(checkout.getEditStatus()).equals(EditStatus.Applied);
|
|
99
|
-
// Is malformed after a malformed edit
|
|
100
|
-
const malformedMove = Change.move({
|
|
101
|
-
start: { side: Side.Before },
|
|
102
|
-
end: { side: Side.After },
|
|
103
|
-
}, { side: Side.After });
|
|
104
|
-
expect(() => checkout.applyChanges(malformedMove)).throws('Locally constructed edits must be well-formed and valid.');
|
|
105
|
-
expect(checkout.getEditStatus()).equals(EditStatus.Malformed);
|
|
106
|
-
// Is still malformed after a subsequent valid edit
|
|
107
|
-
assert.throws(() => checkout.applyChanges(Change.delete(StableRange.only(testTree.left))), (e) => validateAssertionError(e, 'Cannot apply change to an edit unless all previous changes have applied'));
|
|
108
|
-
expect(checkout.getEditStatus()).equals(EditStatus.Malformed);
|
|
109
|
-
checkout.abortEdit();
|
|
110
|
-
// Next edit is unaffected
|
|
111
|
-
checkout.openEdit();
|
|
112
|
-
expect(checkout.getEditStatus()).equals(EditStatus.Applied);
|
|
113
|
-
checkout.closeEdit();
|
|
114
|
-
});
|
|
115
|
-
it('emits error telemetry on attempted close of malformed edits', async () => {
|
|
116
|
-
const events = [];
|
|
117
|
-
const { checkout } = await setUpTestTreeCheckout({
|
|
118
|
-
logger: { send: (event) => event.eventName.includes('Checkout') && events.push(event) },
|
|
119
|
-
});
|
|
120
|
-
checkout.openEdit();
|
|
121
|
-
// Starts as valid
|
|
122
|
-
expect(checkout.getEditStatus()).equals(EditStatus.Applied);
|
|
123
|
-
// Is malformed after a malformed edit
|
|
124
|
-
const malformedMove = Change.move({
|
|
125
|
-
start: { side: Side.Before },
|
|
126
|
-
end: { side: Side.After },
|
|
127
|
-
}, { side: Side.After });
|
|
128
|
-
expect(() => checkout.applyChanges(...malformedMove)).throws('Locally constructed edits must be well-formed and valid.');
|
|
129
|
-
expect(events.length).to.equal(1);
|
|
130
|
-
expect(events[0]).to.deep.equal({
|
|
131
|
-
category: 'error',
|
|
132
|
-
error: 'FailedLocalEdit',
|
|
133
|
-
eventName: 'SharedTree:Checkout:FailedLocalEdit',
|
|
134
|
-
failureKind: 'BadRange',
|
|
135
|
-
isSharedTreeEvent: true,
|
|
136
|
-
rangeFailure: 'BadPlace',
|
|
137
|
-
rangeEndpointFailure: 'Malformed',
|
|
138
|
-
status: 'Malformed',
|
|
139
|
-
});
|
|
140
|
-
assert.throws(() => checkout.closeEdit(), (e) => validateAssertionError(e, /Cannot close a transaction that has already failed./));
|
|
141
|
-
expect(events.length).to.equal(1);
|
|
142
|
-
});
|
|
143
|
-
it('can try to apply an invalid edit and abort without causing an error', async () => {
|
|
144
|
-
const { checkout, tree } = await setUpTestCheckout();
|
|
145
|
-
const simpleTestTree = setUpTestTree(tree);
|
|
146
|
-
// tryApplyEdit aborts when applying an invalid edit and returns undefined
|
|
147
|
-
expect(checkout.tryApplyEdit(Change.insertTree(simpleTestTree.left, StablePlace.after(simpleTestTree.left)))).to.be.undefined;
|
|
148
|
-
// Next edit is unaffected
|
|
149
|
-
checkout.openEdit();
|
|
150
|
-
expect(checkout.getEditStatus()).equals(EditStatus.Applied);
|
|
151
|
-
checkout.closeEdit();
|
|
152
|
-
});
|
|
153
|
-
it('cannot get the edit status if no edit is open', async () => {
|
|
154
|
-
const { checkout } = await setUpTestCheckout();
|
|
155
|
-
assert.throws(() => checkout.getEditStatus());
|
|
156
|
-
});
|
|
157
|
-
it('Surfaces error events to SharedTree', async () => {
|
|
158
|
-
const { checkout, tree } = await setUpTestCheckout();
|
|
159
|
-
const message = 'Simulated unexpected error in ViewChange event handler';
|
|
160
|
-
checkout.on(CheckoutEvent.ViewChange, () => {
|
|
161
|
-
throw Error(message);
|
|
162
|
-
});
|
|
163
|
-
let treeErrorHandlerWasCalled = false;
|
|
164
|
-
tree.on('error', (error) => {
|
|
165
|
-
treeErrorHandlerWasCalled = true;
|
|
166
|
-
expect(error).to.have.property('message').that.equals(message);
|
|
167
|
-
});
|
|
168
|
-
// This could alternatively actually cause a ViewChange via application of an edit.
|
|
169
|
-
checkout.emit(CheckoutEvent.ViewChange, checkout.currentView, checkout.currentView);
|
|
170
|
-
expect(treeErrorHandlerWasCalled).equals(true);
|
|
171
|
-
});
|
|
172
|
-
it('exposes the current edit status in the face of valid edits', async () => {
|
|
173
|
-
const { checkout, testTree } = await setUpTestTreeCheckout();
|
|
174
|
-
checkout.openEdit();
|
|
175
|
-
// Starts as valid
|
|
176
|
-
expect(checkout.getEditStatus()).equals(EditStatus.Applied);
|
|
177
|
-
// Is still valid after a valid edit
|
|
178
|
-
checkout.applyChanges(Change.delete(StableRange.only(testTree.left)));
|
|
179
|
-
expect(checkout.getEditStatus()).equals(EditStatus.Applied);
|
|
180
|
-
checkout.closeEdit();
|
|
181
|
-
});
|
|
182
|
-
it('exposes the current edit status in the face of invalid edits', async () => {
|
|
183
|
-
const { checkout, testTree } = await setUpTestTreeCheckout();
|
|
184
|
-
checkout.openEdit();
|
|
185
|
-
// Starts as valid
|
|
186
|
-
expect(checkout.getEditStatus()).equals(EditStatus.Applied);
|
|
187
|
-
// Is invalid after an invalid edit
|
|
188
|
-
expect(() => checkout.applyChanges(Change.insertTree(testTree.left, StablePlace.after(testTree.left)))).throws('Locally constructed edits must be well-formed and valid.');
|
|
189
|
-
expect(checkout.getEditStatus()).equals(EditStatus.Invalid);
|
|
190
|
-
// Is still invalid after a subsequent valid edit
|
|
191
|
-
assert.throws(() => checkout.applyChanges(Change.delete(StableRange.only(testTree.left))), (e) => validateAssertionError(e, 'Cannot apply change to an edit unless all previous changes have applied'));
|
|
192
|
-
expect(checkout.getEditStatus()).equals(EditStatus.Invalid);
|
|
193
|
-
assert.throws(() => checkout.closeEdit(), (e) => validateAssertionError(e, /Cannot close a transaction that has already failed./));
|
|
194
|
-
// Next edit is unaffected
|
|
195
|
-
checkout.openEdit();
|
|
196
|
-
expect(checkout.getEditStatus()).equals(EditStatus.Applied);
|
|
197
|
-
checkout.closeEdit();
|
|
198
|
-
});
|
|
199
|
-
it('exposes the current edit status in the face of malformed edits', async () => {
|
|
200
|
-
const { checkout, testTree } = await setUpTestTreeCheckout();
|
|
201
|
-
checkout.openEdit();
|
|
202
|
-
// Starts as valid
|
|
203
|
-
expect(checkout.getEditStatus()).equals(EditStatus.Applied);
|
|
204
|
-
// Is malformed after a malformed edit
|
|
205
|
-
const malformedMove = Change.move({
|
|
206
|
-
start: { side: Side.Before },
|
|
207
|
-
end: { side: Side.After },
|
|
208
|
-
}, { side: Side.After });
|
|
209
|
-
expect(() => checkout.applyChanges(malformedMove)).throws('Locally constructed edits must be well-formed and valid.');
|
|
210
|
-
expect(checkout.getEditStatus()).equals(EditStatus.Malformed);
|
|
211
|
-
// Is still malformed after a subsequent valid edit
|
|
212
|
-
assert.throws(() => checkout.applyChanges(Change.delete(StableRange.only(testTree.left))), (e) => validateAssertionError(e, 'Cannot apply change to an edit unless all previous changes have applied'));
|
|
213
|
-
expect(checkout.getEditStatus()).equals(EditStatus.Malformed);
|
|
214
|
-
assert.throws(() => checkout.closeEdit(), (e) => validateAssertionError(e, /Cannot close a transaction that has already failed./));
|
|
215
|
-
// Next edit is unaffected
|
|
216
|
-
checkout.openEdit();
|
|
217
|
-
expect(checkout.getEditStatus()).equals(EditStatus.Applied);
|
|
218
|
-
checkout.closeEdit();
|
|
219
|
-
});
|
|
220
|
-
it('does not invalidate in response to an empty edit', async () => {
|
|
221
|
-
const invalidations = await countViewChange((checkout) => {
|
|
222
|
-
checkout.openEdit();
|
|
223
|
-
checkout.closeEdit();
|
|
224
|
-
});
|
|
225
|
-
expect(invalidations).equals(0);
|
|
226
|
-
});
|
|
227
|
-
it('records empty edits', async () => {
|
|
228
|
-
const { checkout, tree } = await setUpTestCheckout();
|
|
229
|
-
checkout.openEdit();
|
|
230
|
-
const editId = checkout.closeEdit();
|
|
231
|
-
await checkout.waitForPendingUpdates();
|
|
232
|
-
expect(tree.edits.length).equals(1);
|
|
233
|
-
expect(tree.edits.tryGetEditFromId(editId)).is.not.undefined;
|
|
234
|
-
});
|
|
235
|
-
it('will emit invalidation messages in response to changes', async () => {
|
|
236
|
-
const invalidations = await countViewChange((checkout, simpleTestTree) => {
|
|
237
|
-
checkout.applyEdit(Change.delete(StableRange.only(simpleTestTree.left)));
|
|
238
|
-
});
|
|
239
|
-
expect(invalidations).equals(1);
|
|
240
|
-
});
|
|
241
|
-
it('will emit invalidation messages in response to payload change', async () => {
|
|
242
|
-
const invalidations = await countViewChange((checkout, simpleTestTree) => {
|
|
243
|
-
checkout.applyEdit(Change.setPayload(simpleTestTree.left.identifier, 5));
|
|
244
|
-
});
|
|
245
|
-
expect(invalidations).equals(1);
|
|
246
|
-
});
|
|
247
|
-
it('emits a change event for each batch of changes in a local edit', async () => {
|
|
248
|
-
const changes = await countViewChange(async (checkout, simpleTestTree, data) => {
|
|
249
|
-
checkout.on(CheckoutEvent.ViewChange, () => {
|
|
250
|
-
const leftTrait = checkout.currentView.getTrait(simpleTestTree.left.traitLocation);
|
|
251
|
-
const rightTrait = checkout.currentView.getTrait(simpleTestTree.right.traitLocation);
|
|
252
|
-
if (data.changeCount === 1) {
|
|
253
|
-
expect(leftTrait.length).to.equal(0); // "left" child is deleted...
|
|
254
|
-
expect(rightTrait.length).to.equal(1); // ...but "right" child is not
|
|
255
|
-
}
|
|
256
|
-
else if (data.changeCount === 2) {
|
|
257
|
-
expect(leftTrait.length).to.equal(0); // "left" child is deleted...
|
|
258
|
-
expect(rightTrait.length).to.equal(0); // ...and so is "right" child
|
|
259
|
-
}
|
|
260
|
-
});
|
|
261
|
-
checkout.openEdit();
|
|
262
|
-
expect(data.changeCount).equals(0);
|
|
263
|
-
checkout.applyChanges(Change.delete(StableRange.only(simpleTestTree.left)));
|
|
264
|
-
expect(data.changeCount).equals(1);
|
|
265
|
-
checkout.applyChanges(Change.delete(StableRange.only(simpleTestTree.right)));
|
|
266
|
-
expect(data.changeCount).equals(2);
|
|
267
|
-
checkout.closeEdit();
|
|
268
|
-
await checkout.waitForPendingUpdates();
|
|
269
|
-
});
|
|
270
|
-
// Checkout's use of LogViewer.setKnownEditingResult should enable CachingLogViewer
|
|
271
|
-
// to return the exact same revision view object, allowing checkout to skip an extra change event from closeEdit.
|
|
272
|
-
expect(changes).equals(2);
|
|
273
|
-
});
|
|
274
|
-
it('emits ViewChange events for edits directly on tree', async () => {
|
|
275
|
-
const { checkout, testTree } = await setUpTestTreeCheckout();
|
|
276
|
-
let changeCount = 0;
|
|
277
|
-
checkout.on(CheckoutEvent.ViewChange, () => {
|
|
278
|
-
changeCount += 1;
|
|
279
|
-
});
|
|
280
|
-
expect(changeCount).equals(0);
|
|
281
|
-
checkout.tree.applyEdit(Change.delete(StableRange.only(testTree.left)));
|
|
282
|
-
// Wait for edit to be included in checkout.
|
|
283
|
-
await checkout.waitForPendingUpdates();
|
|
284
|
-
expect(changeCount).equals(1);
|
|
285
|
-
});
|
|
286
|
-
it('automatically loads views from edits committed directly on it', async () => {
|
|
287
|
-
const { checkout, testTree } = await setUpTestTreeCheckout();
|
|
288
|
-
const viewBefore = checkout.currentView;
|
|
289
|
-
let changeCount = 0;
|
|
290
|
-
checkout.on(CheckoutEvent.ViewChange, () => {
|
|
291
|
-
changeCount += 1;
|
|
292
|
-
});
|
|
293
|
-
checkout.applyEdit(Change.delete(StableRange.only(testTree.left)));
|
|
294
|
-
expect(changeCount).equals(1);
|
|
295
|
-
expect(viewBefore.equals(checkout.currentView)).to.be.false;
|
|
296
|
-
});
|
|
297
|
-
const secondTreeOptions = {
|
|
298
|
-
id: 'secondTestSharedTree',
|
|
299
|
-
localMode: false,
|
|
300
|
-
allowInvalid: true,
|
|
301
|
-
};
|
|
302
|
-
it('can wait on edits to be submitted', async () => {
|
|
303
|
-
const { checkout, testTree } = await setUpTestTreeCheckout();
|
|
304
|
-
let committedEditsCount = 0;
|
|
305
|
-
checkout.tree.on(SharedTreeEvent.EditCommitted, () => {
|
|
306
|
-
committedEditsCount += 1;
|
|
307
|
-
});
|
|
308
|
-
expect(committedEditsCount).equals(0);
|
|
309
|
-
checkout.tree.applyEdit(Change.delete(StableRange.only(testTree.left)));
|
|
310
|
-
await checkout.waitForEditsToSubmit();
|
|
311
|
-
expect(committedEditsCount).equals(1);
|
|
312
|
-
});
|
|
313
|
-
it('emits ViewChange events for remote edits', async () => {
|
|
314
|
-
const { containerRuntimeFactory, tree } = setUpTestSharedTree({ localMode: false });
|
|
315
|
-
const simpleTestTree = setUpTestTree(tree);
|
|
316
|
-
const { tree: secondTree } = setUpTestSharedTree({
|
|
317
|
-
containerRuntimeFactory,
|
|
318
|
-
...secondTreeOptions,
|
|
319
|
-
});
|
|
320
|
-
containerRuntimeFactory.processAllMessages();
|
|
321
|
-
const checkout = await checkoutFactory(tree);
|
|
322
|
-
let changeCount = 0;
|
|
323
|
-
checkout.on(CheckoutEvent.ViewChange, () => {
|
|
324
|
-
changeCount += 1;
|
|
325
|
-
});
|
|
326
|
-
secondTree.applyEdit(Change.delete(StableRange.only(simpleTestTree.left.translateId(secondTree))));
|
|
327
|
-
expect(changeCount).equals(0);
|
|
328
|
-
containerRuntimeFactory.processAllMessages();
|
|
329
|
-
// Wait for edit to be included in checkout.
|
|
330
|
-
await checkout.waitForPendingUpdates();
|
|
331
|
-
expect(changeCount).equals(1);
|
|
332
|
-
expect(secondTree.equals(tree));
|
|
333
|
-
});
|
|
334
|
-
it('connected state with a remote SharedTree equates correctly during edits', async () => {
|
|
335
|
-
// Invalid edits are allowed here because this test creates edits concurrently in two trees,
|
|
336
|
-
// which after syncing, end up with one being invalid.
|
|
337
|
-
const { tree, containerRuntimeFactory } = setUpTestSharedTree({ localMode: false, allowInvalid: true });
|
|
338
|
-
const simpleTestTree = setUpTestTree(tree);
|
|
339
|
-
const { tree: secondTree } = setUpTestSharedTree({
|
|
340
|
-
containerRuntimeFactory,
|
|
341
|
-
...secondTreeOptions,
|
|
342
|
-
});
|
|
343
|
-
containerRuntimeFactory.processAllMessages();
|
|
344
|
-
const checkout = await checkoutFactory(tree);
|
|
345
|
-
const secondCheckout = await checkoutFactory(tree);
|
|
346
|
-
expect(checkout.currentView.equals(secondCheckout.currentView)).to.be.true;
|
|
347
|
-
expect(checkout.currentView.hasEqualForest(secondCheckout.currentView)).to.be.true;
|
|
348
|
-
checkout.openEdit();
|
|
349
|
-
expect(checkout.currentView.equals(secondCheckout.currentView)).to.be.false;
|
|
350
|
-
expect(checkout.currentView.hasEqualForest(secondCheckout.currentView)).to.be.true;
|
|
351
|
-
expect(tree.equals(secondTree)).to.be.true;
|
|
352
|
-
secondCheckout.openEdit();
|
|
353
|
-
expect(checkout.currentView.equals(secondCheckout.currentView)).to.be.true;
|
|
354
|
-
expect(checkout.currentView.hasEqualForest(secondCheckout.currentView)).to.be.true;
|
|
355
|
-
expect(tree.equals(secondTree)).to.be.true;
|
|
356
|
-
checkout.applyChanges(Change.delete(StableRange.only(simpleTestTree.left)));
|
|
357
|
-
expect(checkout.currentView.equals(secondCheckout.currentView)).to.be.false;
|
|
358
|
-
expect(checkout.currentView.hasEqualForest(secondCheckout.currentView)).to.be.false;
|
|
359
|
-
secondCheckout.applyChanges(Change.delete(StableRange.only(simpleTestTree.left)));
|
|
360
|
-
expect(checkout.currentView.equals(secondCheckout.currentView)).to.be.true;
|
|
361
|
-
expect(checkout.currentView.hasEqualForest(secondCheckout.currentView)).to.be.true;
|
|
362
|
-
expect(tree.equals(secondTree)).to.be.true;
|
|
363
|
-
checkout.closeEdit();
|
|
364
|
-
await checkout.waitForPendingUpdates();
|
|
365
|
-
expect(checkout.currentView.equals(secondCheckout.currentView)).to.be.false;
|
|
366
|
-
expect(checkout.currentView.hasEqualForest(secondCheckout.currentView)).to.be.true;
|
|
367
|
-
secondCheckout.closeEdit();
|
|
368
|
-
await secondCheckout.waitForPendingUpdates();
|
|
369
|
-
expect(checkout.currentView.equals(secondCheckout.currentView)).to.be.true;
|
|
370
|
-
expect(checkout.currentView.hasEqualForest(secondCheckout.currentView)).to.be.true;
|
|
371
|
-
await checkout.waitForPendingUpdates();
|
|
372
|
-
await secondCheckout.waitForPendingUpdates();
|
|
373
|
-
containerRuntimeFactory.processAllMessages();
|
|
374
|
-
expect(tree.equals(secondTree)).to.be.true;
|
|
375
|
-
await checkout.waitForPendingUpdates();
|
|
376
|
-
await secondCheckout.waitForPendingUpdates();
|
|
377
|
-
expect(checkout.currentView.equals(secondCheckout.currentView)).to.be.true;
|
|
378
|
-
expect(checkout.currentView.hasEqualForest(secondCheckout.currentView)).to.be.true;
|
|
379
|
-
});
|
|
380
|
-
it('can successfully rebase an ongoing local edit', async () => {
|
|
381
|
-
const { tree, containerRuntimeFactory } = setUpTestSharedTree({ localMode: false });
|
|
382
|
-
const simpleTestTree = setUpTestTree(tree);
|
|
383
|
-
const { tree: secondTree } = setUpTestSharedTree({ containerRuntimeFactory, ...secondTreeOptions });
|
|
384
|
-
// Sync initial tree
|
|
385
|
-
containerRuntimeFactory.processAllMessages();
|
|
386
|
-
const checkout = await checkoutFactory(tree);
|
|
387
|
-
const secondCheckout = await checkoutFactory(secondTree);
|
|
388
|
-
const newLeftNode = simpleTestTree.buildLeaf(simpleTestTree.generateNodeId());
|
|
389
|
-
checkout.openEdit();
|
|
390
|
-
checkout.applyChanges(setTrait(simpleTestTree.left.traitLocation, [newLeftNode]));
|
|
391
|
-
// Concurrently, the second client deletes the right node. This will not conflict with the operation performed
|
|
392
|
-
// on the left trait on the first client.
|
|
393
|
-
secondCheckout.applyEdit(Change.delete(StableRange.only(simpleTestTree.right.translateId(secondTree))));
|
|
394
|
-
await secondCheckout.waitForPendingUpdates();
|
|
395
|
-
// Deliver the remote change. Since there will not be any conflicts, the result should merge locally and both trait
|
|
396
|
-
// modifications should be reflected in the current view.
|
|
397
|
-
containerRuntimeFactory.processAllMessages();
|
|
398
|
-
await checkout.waitForPendingUpdates();
|
|
399
|
-
await secondCheckout.waitForPendingUpdates();
|
|
400
|
-
let leftTrait = checkout.currentView.getTrait(simpleTestTree.left.traitLocation);
|
|
401
|
-
let rightTrait = checkout.currentView.getTrait(simpleTestTree.right.traitLocation);
|
|
402
|
-
expect(leftTrait).deep.equals([newLeftNode.identifier]);
|
|
403
|
-
// The remote deletion of the right node, while delivered, will not be reflected in the view yet.
|
|
404
|
-
expect(rightTrait).deep.equals([simpleTestTree.right.identifier]);
|
|
405
|
-
const secondLeftTrait = secondCheckout.currentView.getTrait(simpleTestTree.left.traitLocation.translate(secondTree));
|
|
406
|
-
const secondRightTrait = secondCheckout.currentView.getTrait(simpleTestTree.right.traitLocation.translate(secondTree));
|
|
407
|
-
expect(secondLeftTrait).deep.equals([simpleTestTree.left.translateId(secondTree)]);
|
|
408
|
-
expect(secondRightTrait.length).equals(0);
|
|
409
|
-
// Merge in the latest changes.
|
|
410
|
-
await checkout.waitForPendingUpdates();
|
|
411
|
-
const rebaseResult = checkout.rebaseCurrentEdit();
|
|
412
|
-
expect(rebaseResult).equals(EditValidationResult.Valid);
|
|
413
|
-
leftTrait = checkout.currentView.getTrait(simpleTestTree.left.traitLocation);
|
|
414
|
-
rightTrait = checkout.currentView.getTrait(simpleTestTree.right.traitLocation);
|
|
415
|
-
expect(leftTrait).deep.equals([newLeftNode.identifier]);
|
|
416
|
-
expect(rightTrait.length).equals(0);
|
|
417
|
-
checkout.closeEdit();
|
|
418
|
-
// Again, call this prior to processing ops to accommodate PrefetchingCheckout
|
|
419
|
-
await checkout.waitForPendingUpdates();
|
|
420
|
-
containerRuntimeFactory.processAllMessages();
|
|
421
|
-
await secondCheckout.waitForPendingUpdates();
|
|
422
|
-
expect(tree.equals(secondTree)).to.be.true;
|
|
423
|
-
});
|
|
424
|
-
it('can handle a failed rebase of an ongoing local edit', async () => {
|
|
425
|
-
const { tree, containerRuntimeFactory } = setUpTestSharedTree({ localMode: false });
|
|
426
|
-
const simpleTestTree = setUpTestTree(tree);
|
|
427
|
-
const { tree: secondTree } = setUpTestSharedTree({ containerRuntimeFactory, ...secondTreeOptions });
|
|
428
|
-
// Sync initial tree
|
|
429
|
-
containerRuntimeFactory.processAllMessages();
|
|
430
|
-
const checkout = await checkoutFactory(tree);
|
|
431
|
-
const secondCheckout = await checkoutFactory(secondTree);
|
|
432
|
-
checkout.openEdit();
|
|
433
|
-
// Move the left node to after the right node
|
|
434
|
-
checkout.applyChanges(Change.move(StableRange.only(simpleTestTree.left), StablePlace.after(simpleTestTree.right)));
|
|
435
|
-
// Concurrently, the second client deletes the right node. This will conflict with the move operation by the first client.
|
|
436
|
-
secondCheckout.applyEdit(Change.delete(StableRange.only(simpleTestTree.right.translateId(secondTree))));
|
|
437
|
-
await secondCheckout.waitForPendingUpdates();
|
|
438
|
-
containerRuntimeFactory.processAllMessages();
|
|
439
|
-
await checkout.waitForPendingUpdates();
|
|
440
|
-
await secondCheckout.waitForPendingUpdates();
|
|
441
|
-
// Before rebasing, the first client should still see the right node and will have moved the left node after it.
|
|
442
|
-
const leftTrait = checkout.currentView.getTrait(simpleTestTree.left.traitLocation);
|
|
443
|
-
const rightTrait = checkout.currentView.getTrait(simpleTestTree.right.traitLocation);
|
|
444
|
-
expect(leftTrait).deep.equals([]);
|
|
445
|
-
expect(rightTrait).deep.equals([simpleTestTree.right.identifier, simpleTestTree.left.identifier]);
|
|
446
|
-
// Merge in the latest changes.
|
|
447
|
-
const rebaseResult = checkout.rebaseCurrentEdit();
|
|
448
|
-
expect(rebaseResult).equals(EditValidationResult.Invalid);
|
|
449
|
-
expect(areRevisionViewsSemanticallyEqual(checkout.currentView, tree, secondCheckout.currentView, secondTree)).to.be.true;
|
|
450
|
-
});
|
|
451
|
-
it('can dispose and remove listeners', async () => {
|
|
452
|
-
const { checkout } = await setUpTestCheckout();
|
|
453
|
-
expect(checkout.tree.listenerCount(SharedTreeEvent.EditCommitted)).to.equal(1);
|
|
454
|
-
checkout.dispose();
|
|
455
|
-
expect(checkout.tree.listenerCount(SharedTreeEvent.EditCommitted)).to.equal(0);
|
|
456
|
-
});
|
|
457
|
-
additionalTests?.();
|
|
458
|
-
});
|
|
459
|
-
}
|
|
460
|
-
//# sourceMappingURL=Checkout.tests.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"Checkout.tests.js","sourceRoot":"","sources":["../../src/test/Checkout.tests.ts"],"names":[],"mappings":"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","sourcesContent":["/*!\n * Copyright (c) Microsoft Corporation and contributors. All rights reserved.\n * Licensed under the MIT License.\n */\n\nimport { strict as assert } from 'assert';\nimport { validateAssertionError } from '@fluidframework/test-runtime-utils';\nimport { ITelemetryBaseEvent } from '@fluidframework/core-interfaces';\nimport { expect } from 'chai';\nimport {\n\tsetTrait,\n\tEditStatus,\n\tStableRange,\n\tStablePlace,\n\tEditValidationResult,\n\tSharedTree,\n\tSharedTreeEvent,\n\tCheckout,\n\tCheckoutEvent,\n\tChange,\n\tSide,\n\tareRevisionViewsSemanticallyEqual,\n} from '../index.js';\nimport { TestTree } from './utilities/TestNode.js';\nimport { setUpTestSharedTree, SharedTreeTestingOptions, setUpTestTree } from './utilities/TestUtilities.js';\n\n/**\n * Checkout test suite\n */\nexport function checkoutTests(\n\tcheckoutName: string,\n\tcheckoutFactory: (tree: SharedTree) => Promise<Checkout>,\n\tadditionalTests?: () => void\n): void {\n\tasync function setUpTestCheckout(\n\t\toptionsArg?: SharedTreeTestingOptions\n\t): Promise<{ checkout: Checkout; tree: SharedTree }> {\n\t\tconst options = { localMode: true, noFailOnError: true, ...optionsArg };\n\t\tconst { tree } = setUpTestSharedTree(options);\n\t\treturn { checkout: await checkoutFactory(tree), tree };\n\t}\n\n\t/**\n\t * Counts the number of times ViewChange occurs while performing `action`.\n\t * Checks arguments to ViewChange are correct as well.\n\t * @param action - Action to perform\n\t * @param options - Options object used to construct the initial SharedTree\n\t */\n\tasync function countViewChange(\n\t\taction: (checkout: Checkout, simpleTestTree: TestTree, data: { changeCount: number }) => void | Promise<void>,\n\t\toptions: SharedTreeTestingOptions = { localMode: true }\n\t): Promise<number> {\n\t\tconst { checkout, tree } = await setUpTestCheckout(options);\n\t\tconst simpleTestTree = setUpTestTree(tree);\n\t\tawait checkout.waitForPendingUpdates();\n\t\tlet lastView = checkout.currentView;\n\t\tconst data = { changeCount: 0 };\n\t\tcheckout.on(CheckoutEvent.ViewChange, (before, after) => {\n\t\t\texpect(after).equals(checkout.currentView);\n\t\t\texpect(before).equals(lastView);\n\t\t\tlastView = after;\n\t\t\tdata.changeCount++;\n\t\t});\n\t\t// Prevent errors from errors (like failed expects) from being hidden.\n\t\tconst errors: Error[] = [];\n\t\tcheckout.on('error', (error) => {\n\t\t\terrors.push(error);\n\t\t});\n\n\t\tawait action(checkout, simpleTestTree, data);\n\t\texpect(errors).deep.equal([]);\n\t\treturn data.changeCount;\n\t}\n\n\tasync function setUpTestTreeCheckout(options?: SharedTreeTestingOptions): Promise<{\n\t\tcheckout: Checkout;\n\t\tsharedTree: SharedTree;\n\t\ttestTree: TestTree;\n\t}> {\n\t\tconst { checkout, tree } = await setUpTestCheckout(options);\n\t\tconst testTree = setUpTestTree(tree);\n\t\tawait checkout.waitForPendingUpdates();\n\t\treturn { checkout, sharedTree: tree, testTree };\n\t}\n\n\tdescribe(checkoutName, () => {\n\t\tit('can only have one edit open at a time', async () => {\n\t\t\tconst { checkout } = await setUpTestCheckout();\n\t\t\tcheckout.openEdit();\n\t\t\tassert.throws(() => checkout.openEdit());\n\t\t});\n\n\t\tit('can only close an edit if one is open', async () => {\n\t\t\tconst { checkout } = await setUpTestCheckout();\n\t\t\tassert.throws(() => checkout.closeEdit());\n\t\t});\n\n\t\tit('can only apply changes if an edit is open', async () => {\n\t\t\tconst { checkout, testTree } = await setUpTestTreeCheckout();\n\t\t\tassert.throws(() => checkout.applyChanges(Change.delete(StableRange.only(testTree.left))));\n\t\t});\n\n\t\tit('cannot abort an edit if no edit is open', async () => {\n\t\t\tconst { checkout } = await setUpTestCheckout();\n\t\t\tassert.throws(() => checkout.abortEdit());\n\t\t});\n\n\t\tit('can abort valid edits', async () => {\n\t\t\tconst { checkout, testTree } = await setUpTestTreeCheckout();\n\t\t\tcheckout.openEdit();\n\t\t\t// Is still valid after a valid edit\n\t\t\tcheckout.applyChanges(Change.delete(StableRange.only(testTree.left.identifier)));\n\t\t\texpect(checkout.getEditStatus()).equals(EditStatus.Applied);\n\t\t\tcheckout.abortEdit();\n\n\t\t\t// The left node should still be there\n\t\t\texpect(checkout.currentView.getViewNode(testTree.left.identifier).identifier).not.undefined;\n\t\t});\n\n\t\tit('can abort invalid edits', async () => {\n\t\t\tconst { checkout, testTree } = await setUpTestTreeCheckout();\n\t\t\tcheckout.openEdit();\n\t\t\t// Starts as valid\n\t\t\texpect(checkout.getEditStatus()).equals(EditStatus.Applied);\n\n\t\t\t// Is invalid after an invalid edit\n\t\t\texpect(() =>\n\t\t\t\tcheckout.applyChanges(Change.insertTree(testTree.left, StablePlace.after(testTree.left)))\n\t\t\t).throws('Locally constructed edits must be well-formed and valid.');\n\t\t\texpect(checkout.getEditStatus()).equals(EditStatus.Invalid);\n\t\t\tcheckout.abortEdit();\n\n\t\t\t// Next edit is unaffected\n\t\t\tcheckout.openEdit();\n\t\t\texpect(checkout.getEditStatus()).equals(EditStatus.Applied);\n\t\t\tcheckout.closeEdit();\n\t\t});\n\n\t\tit('can abort malformed edits', async () => {\n\t\t\tconst { checkout, testTree } = await setUpTestTreeCheckout();\n\t\t\tcheckout.openEdit();\n\t\t\t// Starts as valid\n\t\t\texpect(checkout.getEditStatus()).equals(EditStatus.Applied);\n\n\t\t\t// Is malformed after a malformed edit\n\t\t\tconst malformedMove = Change.move(\n\t\t\t\t{\n\t\t\t\t\tstart: { side: Side.Before },\n\t\t\t\t\tend: { side: Side.After },\n\t\t\t\t},\n\t\t\t\t{ side: Side.After }\n\t\t\t);\n\t\t\texpect(() => checkout.applyChanges(malformedMove)).throws(\n\t\t\t\t'Locally constructed edits must be well-formed and valid.'\n\t\t\t);\n\t\t\texpect(checkout.getEditStatus()).equals(EditStatus.Malformed);\n\n\t\t\t// Is still malformed after a subsequent valid edit\n\t\t\tassert.throws(\n\t\t\t\t() => checkout.applyChanges(Change.delete(StableRange.only(testTree.left))),\n\t\t\t\t(e: Error) =>\n\t\t\t\t\tvalidateAssertionError(e, 'Cannot apply change to an edit unless all previous changes have applied')\n\t\t\t);\n\t\t\texpect(checkout.getEditStatus()).equals(EditStatus.Malformed);\n\n\t\t\tcheckout.abortEdit();\n\n\t\t\t// Next edit is unaffected\n\t\t\tcheckout.openEdit();\n\t\t\texpect(checkout.getEditStatus()).equals(EditStatus.Applied);\n\t\t\tcheckout.closeEdit();\n\t\t});\n\n\t\tit('emits error telemetry on attempted close of malformed edits', async () => {\n\t\t\tconst events: ITelemetryBaseEvent[] = [];\n\t\t\tconst { checkout } = await setUpTestTreeCheckout({\n\t\t\t\tlogger: { send: (event) => event.eventName.includes('Checkout') && events.push(event) },\n\t\t\t});\n\t\t\tcheckout.openEdit();\n\t\t\t// Starts as valid\n\t\t\texpect(checkout.getEditStatus()).equals(EditStatus.Applied);\n\n\t\t\t// Is malformed after a malformed edit\n\t\t\tconst malformedMove = Change.move(\n\t\t\t\t{\n\t\t\t\t\tstart: { side: Side.Before },\n\t\t\t\t\tend: { side: Side.After },\n\t\t\t\t},\n\t\t\t\t{ side: Side.After }\n\t\t\t);\n\t\t\texpect(() => checkout.applyChanges(...malformedMove)).throws(\n\t\t\t\t'Locally constructed edits must be well-formed and valid.'\n\t\t\t);\n\t\t\texpect(events.length).to.equal(1);\n\t\t\texpect(events[0]).to.deep.equal({\n\t\t\t\tcategory: 'error',\n\t\t\t\terror: 'FailedLocalEdit',\n\t\t\t\teventName: 'SharedTree:Checkout:FailedLocalEdit',\n\t\t\t\tfailureKind: 'BadRange',\n\t\t\t\tisSharedTreeEvent: true,\n\t\t\t\trangeFailure: 'BadPlace',\n\t\t\t\trangeEndpointFailure: 'Malformed',\n\t\t\t\tstatus: 'Malformed',\n\t\t\t});\n\n\t\t\tassert.throws(\n\t\t\t\t() => checkout.closeEdit(),\n\t\t\t\t(e: Error) => validateAssertionError(e, /Cannot close a transaction that has already failed./)\n\t\t\t);\n\t\t\texpect(events.length).to.equal(1);\n\t\t});\n\n\t\tit('can try to apply an invalid edit and abort without causing an error', async () => {\n\t\t\tconst { checkout, tree } = await setUpTestCheckout();\n\t\t\tconst simpleTestTree = setUpTestTree(tree);\n\n\t\t\t// tryApplyEdit aborts when applying an invalid edit and returns undefined\n\t\t\texpect(\n\t\t\t\tcheckout.tryApplyEdit(Change.insertTree(simpleTestTree.left, StablePlace.after(simpleTestTree.left)))\n\t\t\t).to.be.undefined;\n\n\t\t\t// Next edit is unaffected\n\t\t\tcheckout.openEdit();\n\t\t\texpect(checkout.getEditStatus()).equals(EditStatus.Applied);\n\t\t\tcheckout.closeEdit();\n\t\t});\n\n\t\tit('cannot get the edit status if no edit is open', async () => {\n\t\t\tconst { checkout } = await setUpTestCheckout();\n\t\t\tassert.throws(() => checkout.getEditStatus());\n\t\t});\n\n\t\tit('Surfaces error events to SharedTree', async () => {\n\t\t\tconst { checkout, tree } = await setUpTestCheckout();\n\t\t\tconst message = 'Simulated unexpected error in ViewChange event handler';\n\t\t\tcheckout.on(CheckoutEvent.ViewChange, () => {\n\t\t\t\tthrow Error(message);\n\t\t\t});\n\t\t\tlet treeErrorHandlerWasCalled = false;\n\t\t\ttree.on('error', (error) => {\n\t\t\t\ttreeErrorHandlerWasCalled = true;\n\t\t\t\texpect(error).to.have.property('message').that.equals(message);\n\t\t\t});\n\n\t\t\t// This could alternatively actually cause a ViewChange via application of an edit.\n\t\t\tcheckout.emit(CheckoutEvent.ViewChange, checkout.currentView, checkout.currentView);\n\t\t\texpect(treeErrorHandlerWasCalled).equals(true);\n\t\t});\n\n\t\tit('exposes the current edit status in the face of valid edits', async () => {\n\t\t\tconst { checkout, testTree } = await setUpTestTreeCheckout();\n\t\t\tcheckout.openEdit();\n\t\t\t// Starts as valid\n\t\t\texpect(checkout.getEditStatus()).equals(EditStatus.Applied);\n\n\t\t\t// Is still valid after a valid edit\n\t\t\tcheckout.applyChanges(Change.delete(StableRange.only(testTree.left)));\n\t\t\texpect(checkout.getEditStatus()).equals(EditStatus.Applied);\n\n\t\t\tcheckout.closeEdit();\n\t\t});\n\n\t\tit('exposes the current edit status in the face of invalid edits', async () => {\n\t\t\tconst { checkout, testTree } = await setUpTestTreeCheckout();\n\t\t\tcheckout.openEdit();\n\t\t\t// Starts as valid\n\t\t\texpect(checkout.getEditStatus()).equals(EditStatus.Applied);\n\n\t\t\t// Is invalid after an invalid edit\n\t\t\texpect(() =>\n\t\t\t\tcheckout.applyChanges(Change.insertTree(testTree.left, StablePlace.after(testTree.left)))\n\t\t\t).throws('Locally constructed edits must be well-formed and valid.');\n\t\t\texpect(checkout.getEditStatus()).equals(EditStatus.Invalid);\n\n\t\t\t// Is still invalid after a subsequent valid edit\n\t\t\tassert.throws(\n\t\t\t\t() => checkout.applyChanges(Change.delete(StableRange.only(testTree.left))),\n\t\t\t\t(e: Error) =>\n\t\t\t\t\tvalidateAssertionError(e, 'Cannot apply change to an edit unless all previous changes have applied')\n\t\t\t);\n\t\t\texpect(checkout.getEditStatus()).equals(EditStatus.Invalid);\n\n\t\t\tassert.throws(\n\t\t\t\t() => checkout.closeEdit(),\n\t\t\t\t(e: Error) => validateAssertionError(e, /Cannot close a transaction that has already failed./)\n\t\t\t);\n\n\t\t\t// Next edit is unaffected\n\t\t\tcheckout.openEdit();\n\t\t\texpect(checkout.getEditStatus()).equals(EditStatus.Applied);\n\t\t\tcheckout.closeEdit();\n\t\t});\n\n\t\tit('exposes the current edit status in the face of malformed edits', async () => {\n\t\t\tconst { checkout, testTree } = await setUpTestTreeCheckout();\n\t\t\tcheckout.openEdit();\n\t\t\t// Starts as valid\n\t\t\texpect(checkout.getEditStatus()).equals(EditStatus.Applied);\n\n\t\t\t// Is malformed after a malformed edit\n\t\t\tconst malformedMove = Change.move(\n\t\t\t\t{\n\t\t\t\t\tstart: { side: Side.Before },\n\t\t\t\t\tend: { side: Side.After },\n\t\t\t\t},\n\t\t\t\t{ side: Side.After }\n\t\t\t);\n\t\t\texpect(() => checkout.applyChanges(malformedMove)).throws(\n\t\t\t\t'Locally constructed edits must be well-formed and valid.'\n\t\t\t);\n\t\t\texpect(checkout.getEditStatus()).equals(EditStatus.Malformed);\n\n\t\t\t// Is still malformed after a subsequent valid edit\n\t\t\tassert.throws(\n\t\t\t\t() => checkout.applyChanges(Change.delete(StableRange.only(testTree.left))),\n\t\t\t\t(e: Error) =>\n\t\t\t\t\tvalidateAssertionError(e, 'Cannot apply change to an edit unless all previous changes have applied')\n\t\t\t);\n\t\t\texpect(checkout.getEditStatus()).equals(EditStatus.Malformed);\n\n\t\t\tassert.throws(\n\t\t\t\t() => checkout.closeEdit(),\n\t\t\t\t(e: Error) => validateAssertionError(e, /Cannot close a transaction that has already failed./)\n\t\t\t);\n\n\t\t\t// Next edit is unaffected\n\t\t\tcheckout.openEdit();\n\t\t\texpect(checkout.getEditStatus()).equals(EditStatus.Applied);\n\t\t\tcheckout.closeEdit();\n\t\t});\n\n\t\tit('does not invalidate in response to an empty edit', async () => {\n\t\t\tconst invalidations = await countViewChange((checkout) => {\n\t\t\t\tcheckout.openEdit();\n\t\t\t\tcheckout.closeEdit();\n\t\t\t});\n\t\t\texpect(invalidations).equals(0);\n\t\t});\n\n\t\tit('records empty edits', async () => {\n\t\t\tconst { checkout, tree } = await setUpTestCheckout();\n\t\t\tcheckout.openEdit();\n\t\t\tconst editId = checkout.closeEdit();\n\t\t\tawait checkout.waitForPendingUpdates();\n\t\t\texpect(tree.edits.length).equals(1);\n\t\t\texpect(tree.edits.tryGetEditFromId(editId)).is.not.undefined;\n\t\t});\n\n\t\tit('will emit invalidation messages in response to changes', async () => {\n\t\t\tconst invalidations = await countViewChange((checkout, simpleTestTree) => {\n\t\t\t\tcheckout.applyEdit(Change.delete(StableRange.only(simpleTestTree.left)));\n\t\t\t});\n\t\t\texpect(invalidations).equals(1);\n\t\t});\n\n\t\tit('will emit invalidation messages in response to payload change', async () => {\n\t\t\tconst invalidations = await countViewChange((checkout, simpleTestTree) => {\n\t\t\t\tcheckout.applyEdit(Change.setPayload(simpleTestTree.left.identifier, 5));\n\t\t\t});\n\t\t\texpect(invalidations).equals(1);\n\t\t});\n\n\t\tit('emits a change event for each batch of changes in a local edit', async () => {\n\t\t\tconst changes = await countViewChange(async (checkout, simpleTestTree, data) => {\n\t\t\t\tcheckout.on(CheckoutEvent.ViewChange, () => {\n\t\t\t\t\tconst leftTrait = checkout.currentView.getTrait(simpleTestTree.left.traitLocation);\n\t\t\t\t\tconst rightTrait = checkout.currentView.getTrait(simpleTestTree.right.traitLocation);\n\n\t\t\t\t\tif (data.changeCount === 1) {\n\t\t\t\t\t\texpect(leftTrait.length).to.equal(0); // \"left\" child is deleted...\n\t\t\t\t\t\texpect(rightTrait.length).to.equal(1); // ...but \"right\" child is not\n\t\t\t\t\t} else if (data.changeCount === 2) {\n\t\t\t\t\t\texpect(leftTrait.length).to.equal(0); // \"left\" child is deleted...\n\t\t\t\t\t\texpect(rightTrait.length).to.equal(0); // ...and so is \"right\" child\n\t\t\t\t\t}\n\t\t\t\t});\n\n\t\t\t\tcheckout.openEdit();\n\t\t\t\texpect(data.changeCount).equals(0);\n\t\t\t\tcheckout.applyChanges(Change.delete(StableRange.only(simpleTestTree.left)));\n\t\t\t\texpect(data.changeCount).equals(1);\n\t\t\t\tcheckout.applyChanges(Change.delete(StableRange.only(simpleTestTree.right)));\n\t\t\t\texpect(data.changeCount).equals(2);\n\t\t\t\tcheckout.closeEdit();\n\t\t\t\tawait checkout.waitForPendingUpdates();\n\t\t\t});\n\n\t\t\t// Checkout's use of LogViewer.setKnownEditingResult should enable CachingLogViewer\n\t\t\t// to return the exact same revision view object, allowing checkout to skip an extra change event from closeEdit.\n\t\t\texpect(changes).equals(2);\n\t\t});\n\n\t\tit('emits ViewChange events for edits directly on tree', async () => {\n\t\t\tconst { checkout, testTree } = await setUpTestTreeCheckout();\n\t\t\tlet changeCount = 0;\n\t\t\tcheckout.on(CheckoutEvent.ViewChange, () => {\n\t\t\t\tchangeCount += 1;\n\t\t\t});\n\t\t\texpect(changeCount).equals(0);\n\t\t\tcheckout.tree.applyEdit(Change.delete(StableRange.only(testTree.left)));\n\t\t\t// Wait for edit to be included in checkout.\n\t\t\tawait checkout.waitForPendingUpdates();\n\t\t\texpect(changeCount).equals(1);\n\t\t});\n\n\t\tit('automatically loads views from edits committed directly on it', async () => {\n\t\t\tconst { checkout, testTree } = await setUpTestTreeCheckout();\n\t\t\tconst viewBefore = checkout.currentView;\n\t\t\tlet changeCount = 0;\n\t\t\tcheckout.on(CheckoutEvent.ViewChange, () => {\n\t\t\t\tchangeCount += 1;\n\t\t\t});\n\t\t\tcheckout.applyEdit(Change.delete(StableRange.only(testTree.left)));\n\t\t\texpect(changeCount).equals(1);\n\t\t\texpect(viewBefore.equals(checkout.currentView)).to.be.false;\n\t\t});\n\n\t\tconst secondTreeOptions = {\n\t\t\tid: 'secondTestSharedTree',\n\t\t\tlocalMode: false,\n\t\t\tallowInvalid: true,\n\t\t};\n\n\t\tit('can wait on edits to be submitted', async () => {\n\t\t\tconst { checkout, testTree } = await setUpTestTreeCheckout();\n\t\t\tlet committedEditsCount = 0;\n\t\t\tcheckout.tree.on(SharedTreeEvent.EditCommitted, () => {\n\t\t\t\tcommittedEditsCount += 1;\n\t\t\t});\n\t\t\texpect(committedEditsCount).equals(0);\n\t\t\tcheckout.tree.applyEdit(Change.delete(StableRange.only(testTree.left)));\n\t\t\tawait checkout.waitForEditsToSubmit();\n\t\t\texpect(committedEditsCount).equals(1);\n\t\t});\n\n\t\tit('emits ViewChange events for remote edits', async () => {\n\t\t\tconst { containerRuntimeFactory, tree } = setUpTestSharedTree({ localMode: false });\n\t\t\tconst simpleTestTree = setUpTestTree(tree);\n\n\t\t\tconst { tree: secondTree } = setUpTestSharedTree({\n\t\t\t\tcontainerRuntimeFactory,\n\t\t\t\t...secondTreeOptions,\n\t\t\t});\n\n\t\t\tcontainerRuntimeFactory.processAllMessages();\n\t\t\tconst checkout = await checkoutFactory(tree);\n\n\t\t\tlet changeCount = 0;\n\t\t\tcheckout.on(CheckoutEvent.ViewChange, () => {\n\t\t\t\tchangeCount += 1;\n\t\t\t});\n\n\t\t\tsecondTree.applyEdit(Change.delete(StableRange.only(simpleTestTree.left.translateId(secondTree))));\n\t\t\texpect(changeCount).equals(0);\n\t\t\tcontainerRuntimeFactory.processAllMessages();\n\t\t\t// Wait for edit to be included in checkout.\n\t\t\tawait checkout.waitForPendingUpdates();\n\t\t\texpect(changeCount).equals(1);\n\t\t\texpect(secondTree.equals(tree));\n\t\t});\n\n\t\tit('connected state with a remote SharedTree equates correctly during edits', async () => {\n\t\t\t// Invalid edits are allowed here because this test creates edits concurrently in two trees,\n\t\t\t// which after syncing, end up with one being invalid.\n\t\t\tconst { tree, containerRuntimeFactory } = setUpTestSharedTree({ localMode: false, allowInvalid: true });\n\t\t\tconst simpleTestTree = setUpTestTree(tree);\n\t\t\tconst { tree: secondTree } = setUpTestSharedTree({\n\t\t\t\tcontainerRuntimeFactory,\n\t\t\t\t...secondTreeOptions,\n\t\t\t});\n\n\t\t\tcontainerRuntimeFactory.processAllMessages();\n\t\t\tconst checkout = await checkoutFactory(tree);\n\t\t\tconst secondCheckout = await checkoutFactory(tree);\n\n\t\t\texpect(checkout.currentView.equals(secondCheckout.currentView)).to.be.true;\n\t\t\texpect(checkout.currentView.hasEqualForest(secondCheckout.currentView)).to.be.true;\n\t\t\tcheckout.openEdit();\n\t\t\texpect(checkout.currentView.equals(secondCheckout.currentView)).to.be.false;\n\t\t\texpect(checkout.currentView.hasEqualForest(secondCheckout.currentView)).to.be.true;\n\t\t\texpect(tree.equals(secondTree)).to.be.true;\n\t\t\tsecondCheckout.openEdit();\n\t\t\texpect(checkout.currentView.equals(secondCheckout.currentView)).to.be.true;\n\t\t\texpect(checkout.currentView.hasEqualForest(secondCheckout.currentView)).to.be.true;\n\t\t\texpect(tree.equals(secondTree)).to.be.true;\n\t\t\tcheckout.applyChanges(Change.delete(StableRange.only(simpleTestTree.left)));\n\t\t\texpect(checkout.currentView.equals(secondCheckout.currentView)).to.be.false;\n\t\t\texpect(checkout.currentView.hasEqualForest(secondCheckout.currentView)).to.be.false;\n\t\t\tsecondCheckout.applyChanges(Change.delete(StableRange.only(simpleTestTree.left)));\n\t\t\texpect(checkout.currentView.equals(secondCheckout.currentView)).to.be.true;\n\t\t\texpect(checkout.currentView.hasEqualForest(secondCheckout.currentView)).to.be.true;\n\t\t\texpect(tree.equals(secondTree)).to.be.true;\n\t\t\tcheckout.closeEdit();\n\t\t\tawait checkout.waitForPendingUpdates();\n\t\t\texpect(checkout.currentView.equals(secondCheckout.currentView)).to.be.false;\n\t\t\texpect(checkout.currentView.hasEqualForest(secondCheckout.currentView)).to.be.true;\n\t\t\tsecondCheckout.closeEdit();\n\t\t\tawait secondCheckout.waitForPendingUpdates();\n\t\t\texpect(checkout.currentView.equals(secondCheckout.currentView)).to.be.true;\n\t\t\texpect(checkout.currentView.hasEqualForest(secondCheckout.currentView)).to.be.true;\n\t\t\tawait checkout.waitForPendingUpdates();\n\t\t\tawait secondCheckout.waitForPendingUpdates();\n\t\t\tcontainerRuntimeFactory.processAllMessages();\n\t\t\texpect(tree.equals(secondTree)).to.be.true;\n\t\t\tawait checkout.waitForPendingUpdates();\n\t\t\tawait secondCheckout.waitForPendingUpdates();\n\t\t\texpect(checkout.currentView.equals(secondCheckout.currentView)).to.be.true;\n\t\t\texpect(checkout.currentView.hasEqualForest(secondCheckout.currentView)).to.be.true;\n\t\t});\n\n\t\tit('can successfully rebase an ongoing local edit', async () => {\n\t\t\tconst { tree, containerRuntimeFactory } = setUpTestSharedTree({ localMode: false });\n\t\t\tconst simpleTestTree = setUpTestTree(tree);\n\t\t\tconst { tree: secondTree } = setUpTestSharedTree({ containerRuntimeFactory, ...secondTreeOptions });\n\n\t\t\t// Sync initial tree\n\t\t\tcontainerRuntimeFactory.processAllMessages();\n\n\t\t\tconst checkout = await checkoutFactory(tree);\n\t\t\tconst secondCheckout = await checkoutFactory(secondTree);\n\n\t\t\tconst newLeftNode = simpleTestTree.buildLeaf(simpleTestTree.generateNodeId());\n\t\t\tcheckout.openEdit();\n\t\t\tcheckout.applyChanges(setTrait(simpleTestTree.left.traitLocation, [newLeftNode]));\n\n\t\t\t// Concurrently, the second client deletes the right node. This will not conflict with the operation performed\n\t\t\t// on the left trait on the first client.\n\t\t\tsecondCheckout.applyEdit(Change.delete(StableRange.only(simpleTestTree.right.translateId(secondTree))));\n\t\t\tawait secondCheckout.waitForPendingUpdates();\n\n\t\t\t// Deliver the remote change. Since there will not be any conflicts, the result should merge locally and both trait\n\t\t\t// modifications should be reflected in the current view.\n\t\t\tcontainerRuntimeFactory.processAllMessages();\n\n\t\t\tawait checkout.waitForPendingUpdates();\n\t\t\tawait secondCheckout.waitForPendingUpdates();\n\n\t\t\tlet leftTrait = checkout.currentView.getTrait(simpleTestTree.left.traitLocation);\n\t\t\tlet rightTrait = checkout.currentView.getTrait(simpleTestTree.right.traitLocation);\n\t\t\texpect(leftTrait).deep.equals([newLeftNode.identifier]);\n\t\t\t// The remote deletion of the right node, while delivered, will not be reflected in the view yet.\n\t\t\texpect(rightTrait).deep.equals([simpleTestTree.right.identifier]);\n\n\t\t\tconst secondLeftTrait = secondCheckout.currentView.getTrait(\n\t\t\t\tsimpleTestTree.left.traitLocation.translate(secondTree)\n\t\t\t);\n\t\t\tconst secondRightTrait = secondCheckout.currentView.getTrait(\n\t\t\t\tsimpleTestTree.right.traitLocation.translate(secondTree)\n\t\t\t);\n\t\t\texpect(secondLeftTrait).deep.equals([simpleTestTree.left.translateId(secondTree)]);\n\t\t\texpect(secondRightTrait.length).equals(0);\n\n\t\t\t// Merge in the latest changes.\n\t\t\tawait checkout.waitForPendingUpdates();\n\t\t\tconst rebaseResult = checkout.rebaseCurrentEdit();\n\t\t\texpect(rebaseResult).equals(EditValidationResult.Valid);\n\t\t\tleftTrait = checkout.currentView.getTrait(simpleTestTree.left.traitLocation);\n\t\t\trightTrait = checkout.currentView.getTrait(simpleTestTree.right.traitLocation);\n\t\t\texpect(leftTrait).deep.equals([newLeftNode.identifier]);\n\t\t\texpect(rightTrait.length).equals(0);\n\n\t\t\tcheckout.closeEdit();\n\t\t\t// Again, call this prior to processing ops to accommodate PrefetchingCheckout\n\t\t\tawait checkout.waitForPendingUpdates();\n\t\t\tcontainerRuntimeFactory.processAllMessages();\n\t\t\tawait secondCheckout.waitForPendingUpdates();\n\t\t\texpect(tree.equals(secondTree)).to.be.true;\n\t\t});\n\n\t\tit('can handle a failed rebase of an ongoing local edit', async () => {\n\t\t\tconst { tree, containerRuntimeFactory } = setUpTestSharedTree({ localMode: false });\n\t\t\tconst simpleTestTree = setUpTestTree(tree);\n\t\t\tconst { tree: secondTree } = setUpTestSharedTree({ containerRuntimeFactory, ...secondTreeOptions });\n\n\t\t\t// Sync initial tree\n\t\t\tcontainerRuntimeFactory.processAllMessages();\n\n\t\t\tconst checkout = await checkoutFactory(tree);\n\t\t\tconst secondCheckout = await checkoutFactory(secondTree);\n\n\t\t\tcheckout.openEdit();\n\t\t\t// Move the left node to after the right node\n\t\t\tcheckout.applyChanges(\n\t\t\t\tChange.move(StableRange.only(simpleTestTree.left), StablePlace.after(simpleTestTree.right))\n\t\t\t);\n\n\t\t\t// Concurrently, the second client deletes the right node. This will conflict with the move operation by the first client.\n\t\t\tsecondCheckout.applyEdit(Change.delete(StableRange.only(simpleTestTree.right.translateId(secondTree))));\n\t\t\tawait secondCheckout.waitForPendingUpdates();\n\n\t\t\tcontainerRuntimeFactory.processAllMessages();\n\t\t\tawait checkout.waitForPendingUpdates();\n\t\t\tawait secondCheckout.waitForPendingUpdates();\n\n\t\t\t// Before rebasing, the first client should still see the right node and will have moved the left node after it.\n\t\t\tconst leftTrait = checkout.currentView.getTrait(simpleTestTree.left.traitLocation);\n\t\t\tconst rightTrait = checkout.currentView.getTrait(simpleTestTree.right.traitLocation);\n\t\t\texpect(leftTrait).deep.equals([]);\n\t\t\texpect(rightTrait).deep.equals([simpleTestTree.right.identifier, simpleTestTree.left.identifier]);\n\n\t\t\t// Merge in the latest changes.\n\t\t\tconst rebaseResult = checkout.rebaseCurrentEdit();\n\t\t\texpect(rebaseResult).equals(EditValidationResult.Invalid);\n\t\t\texpect(\n\t\t\t\tareRevisionViewsSemanticallyEqual(checkout.currentView, tree, secondCheckout.currentView, secondTree)\n\t\t\t).to.be.true;\n\t\t});\n\n\t\tit('can dispose and remove listeners', async () => {\n\t\t\tconst { checkout } = await setUpTestCheckout();\n\t\t\texpect(checkout.tree.listenerCount(SharedTreeEvent.EditCommitted)).to.equal(1);\n\t\t\tcheckout.dispose();\n\t\t\texpect(checkout.tree.listenerCount(SharedTreeEvent.EditCommitted)).to.equal(0);\n\t\t});\n\n\t\tadditionalTests?.();\n\t});\n}\n"]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"Common.tests.d.ts","sourceRoot":"","sources":["../../src/test/Common.tests.ts"],"names":[],"mappings":"AAAA;;;GAGG"}
|