public async Task AssertSideEffectsAsync(ExpectedSideEffects sideEffects) { if (this.tables.Count == 0) { throw new Exception("No snapshot found. Did you forget to take a snapshot?"); } var stopwatch = Stopwatch.StartNew(); if (object.ReferenceEquals(sideEffects, ExpectedSideEffects.TransactionAborted)) { if (Transaction.Current.TransactionInformation.Status != TransactionStatus.Aborted) { Assert.Fail("Transaction was not aborted."); } // We can't check anything else if the transaction is aborted. return; } using (var databaseContext = this.testDatabase.CreateContext()) { databaseContext.Configuration.AutoDetectChangesEnabled = false; databaseContext.Configuration.LazyLoadingEnabled = false; databaseContext.Configuration.ValidateOnSaveEnabled = false; databaseContext.Configuration.ProxyCreationEnabled = false; foreach (var table in this.tables) { table.GetLatestFromDatabase(databaseContext); } } Trace.WriteLine(string.Format("Queried latest in {0}s", Math.Round(stopwatch.Elapsed.TotalSeconds, 2))); stopwatch = Stopwatch.StartNew(); foreach (var table in this.tables) { this.AssertNoUnexpectedSideEffects(table.Snapshot, table.Database, sideEffects); } Trace.WriteLine(string.Format("Asserted no unexpected side effects in {0}s", Math.Round(stopwatch.Elapsed.TotalSeconds, 2))); stopwatch = Stopwatch.StartNew(); var snapshot = this.tables.SelectMany(_ => _.Snapshot).ToList(); var database = this.tables.SelectMany(_ => _.Database).ToList(); this.AssertExpectedSideEffects(snapshot, database, sideEffects); Trace.WriteLine(string.Format("Asserted expected side effects in {0}s", Math.Round(stopwatch.Elapsed.TotalSeconds, 2))); }
private void AssertExpectedSideEffects(IReadOnlyCollection <IIdentityEquatable> snapshot, IReadOnlyCollection <IIdentityEquatable> database, ExpectedSideEffects sideEffects) { if (sideEffects.Inserts != null) { foreach (var insert in sideEffects.Inserts) { // We call insert.IdentityEquals because it doesn't enforce type checking (it may be an IWildcardEntity). Assert.IsTrue(database.Any(_ => insert.IdentityEquals(_)), "Insert was not applied"); Assert.IsTrue(database.Any(_ => AreEntitiesEqual(insert, _)), "Insert was applied, but not with expected fields"); Assert.IsTrue(snapshot.All(_ => !insert.IdentityEquals(_)), "Cannot assert insert on entity that already exists in snapshot"); } } if (sideEffects.Updates != null) { foreach (var update in sideEffects.Updates) { Assert.IsTrue(database.Any(_ => AreEntitiesEqual(update, _)), "Update was not applied"); Assert.IsTrue(snapshot.All(_ => !AreEntitiesEqual(update, _)), "Cannot assert update on entity that has not changed since the snapshot"); Assert.IsTrue(snapshot.Any(_ => update.IdentityEquals(_)), "Cannot assert update on entity that does not exist in snapshot"); } } if (sideEffects.Deletes != null) { foreach (var delete in sideEffects.Deletes) { Assert.IsTrue(database.All(_ => !_.IdentityEquals(delete)), "Delete was not applied"); } } }
private void AssertNoUnexpectedSideEffects(IReadOnlyCollection <IIdentityEquatable> snapshot, IReadOnlyCollection <IIdentityEquatable> database, ExpectedSideEffects sideEffects) { foreach (var databaseEntity in database) { if (sideEffects.ExcludedFromTest != null && sideEffects.ExcludedFromTest(databaseEntity)) { continue; } var snapshotEntity = snapshot.FirstOrDefault(_ => _.IdentityEquals(databaseEntity)); if (snapshotEntity == null) { if (sideEffects.Inserts == null) { Assert.Fail("Insert was unexpected: " + databaseEntity); } else { Assert.IsTrue(sideEffects.Inserts.Any(_ => AreEntitiesEqual(_, databaseEntity)), "Insert was unexpected: " + databaseEntity); } } else if (!snapshotEntity.Equals(databaseEntity)) { if (sideEffects.Updates == null) { Assert.Fail("Update was unexpected: " + databaseEntity); } else { Assert.IsTrue(sideEffects.Updates.Any(_ => AreEntitiesEqual(_, databaseEntity)), "Update was unexpected: " + databaseEntity); } } } foreach (var snapshotEntity in snapshot) { if (sideEffects.ExcludedFromTest != null && sideEffects.ExcludedFromTest(snapshotEntity)) { continue; } if (database.All(_ => !_.IdentityEquals(snapshotEntity))) { if (sideEffects.Deletes == null) { Assert.Fail("Delete was unexpected: " + snapshotEntity); } else { Assert.IsTrue(sideEffects.Deletes.Any(_ => AreEntitiesEqual(_, snapshotEntity)), "Delete was unexpected: " + snapshotEntity); } } } }