private HttpMethods GetRandomMethodButNotAny() { var result = RandomValueGen.GetRandom <HttpMethods>(); return(result == HttpMethods.Any ? GetRandomMethodButNotAny() : result); }
public void ShouldSet_(string target, string source) { // Arrange var processWindow = RandomValueGen.GetRandom <ProcessWindow>(); var expected = processWindow.GetPropertyValue(source); // Pre-assert // Act var sut = Create(processWindow); var result = sut.GetPropertyValue(target); // Assert Expect(result).To.Deep.Equal(expected); }
public void Copy_GivenSourceReturnsOneCharacterBeforeNewLine_ShouldCallWriteCharWithCharacterBeforeNewline() { //--------------- Set up test pack -------------------- var character = RandomValueGen.GetRandom <char>(); var newLine = '\n'; var writtenChars = new List <char>(); var sut = CreateCopier(c => writtenChars.Add(c), character, newLine); //---------------- Execute Test ---------------------- sut.Copy(); // --------------- Test Result ------------------------ CollectionAssert.AreEqual(writtenChars, new [] { character }); }
public void Copy_GivenSourceReturnsCharacterAfterNewLine_ShouldNotCallWriteCharacterAfterNewLine() { //--------------- Set up test pack -------------------- var characterAfterNewLine = RandomValueGen.GetRandom <char>(); var newLine = '\n'; var writtenChars = new List <char>(); var sut = CreateCopier(c => writtenChars.Add(c), newLine, characterAfterNewLine); //---------------- Execute Test ---------------------- sut.Copy(); // --------------- Test Result ------------------------ CollectionAssert.IsEmpty(writtenChars); }
public void Add_GivenKeyAndValue_ShouldPassThrough() { // Arrange var sut = Create <string, string>(); var kvp = RandomValueGen.GetRandom <KeyValuePair <string, string> >(); // Pre-assert // Act sut.Add(kvp.Key, kvp.Value); // Assert Expect(sut[kvp.Key]).To.Equal(kvp.Value); }
public void TryGetValue_WhenKeyIsKnown_ShouldReturnThatValue() { // Arrange var have = RandomValueGen.GetRandom <KeyValuePair <string, string> >(); var sut = Create <string, string>(); sut.Add(have); // Pre-assert // Act var result = sut.TryGetValue(have.Key, out var found); // Assert Expect(result).To.Be.True(); Expect(found).To.Equal(have.Value); }
public void Clear_ShouldPassThrough() { // Arrange var sut = Create <string, string>(); var item = RandomValueGen.GetRandom <KeyValuePair <string, string> >(); sut.Add(item); // Pre-assert Expect(sut[item.Key]).To.Equal(item.Value); // Act sut.Clear(); // Assert Expect(sut[item.Key]).To.Be.Null(); }
public void Contains_ShouldReturnTrue() { // Arrange var have = RandomValueGen.GetRandom <KeyValuePair <string, string> >(); var missing = RandomValueGen.GetAnother(have); var sut = Create <string, string>(); sut.Add(have); // Pre-assert // Act var haveResult = sut.Contains(have); var missingResult = sut.Contains(missing); // Assert Expect(haveResult).To.Be.True(); Expect(missingResult).To.Be.True(); }
public void Remove_GivenKey_ShouldPassThrough() { // Arrange var have = RandomValueGen.GetRandom <KeyValuePair <string, string> >(); var missing = RandomValueGen.GetAnother(have); var sut = Create <string, string>(); sut.Add(have); Expect(sut[have.Key]).Not.To.Be.Null(); // Pre-assert // Act var haveResult = sut.Remove(have.Key); var missingResult = sut.Remove(missing.Key); // Assert Expect(haveResult).To.Be.True(); Expect(missingResult).To.Be.False(); Expect(sut[have.Key]).To.Be.Null(); }
private void ExpectScriptsCanSupportDatabase(IEnumerable <string> result) { using (var db = new TempDBLocalDb()) { var migrator = new DbSchemaImporter( db.ConnectionString, string.Join("\r\n", result) ); migrator.MigrateToLatest(); var cow = RandomValueGen.GetRandom <Cow>(); using (var ctx = new MooContext(db.CreateConnection())) { ctx.Cows.Add(cow); ctx.SaveChanges(); } using (var ctx = new MooContext(db.CreateConnection())) { var allCows = ctx.Cows.ToArray(); Expect(allCows).To.Contain.Exactly(1).Item(); var stored = allCows[0].DuckAs <ICow>(); Expect(cow.DuckAs <ICow>()).To.Deep.Equal(stored); } } }
public async Task DemonstrateUsage() { // Arrange // you could use the singleton EventAggregator.Instance if you like // or have an instance provided by DI, or even use multiple instances // in your application if that makes sense for the usage var eventAggregator = new EventAggregator(); var loggedInUsers = new List <User>(); // Act // somewhere in the system, we'd like to know when a user logs in... eventAggregator.GetEvent <LoginEvent>() .Subscribe(user => loggedInUsers.Add(user)); eventAggregator.GetEvent <LogoutEvent>() .Subscribe(user => loggedInUsers.Remove(user)); // elsewhere, logins are happening var karen = new User() { Id = 1, Name = "Karen" }; var bob = new User() { Id = 2, Name = "Bob" }; // GetEvent<T> always returns the same event instance, // so if you're going to use it a lot, you can var it // off var loginEvent = eventAggregator.GetEvent <LoginEvent>(); loginEvent.Publish(karen); Expectations.Expect(loggedInUsers) .To.Contain(karen); loginEvent.Publish(bob); Expectations.Expect(loggedInUsers) .To.Contain(bob); // we can suspend messaging: eventAggregator.Suspend(); // now, messages are not processed... // note that publisher threads which use the `Publish` method will suspend too! // -> so for the test, we put this in a task var beforeBarrier = new Barrier(2); var afterBarrier = new Barrier(2); var sam = new User() { Id = 3, Name = "Sam" }; #pragma warning disable 4014 Task.Run(() => { beforeBarrier.SignalAndWait(); loginEvent.Publish(sam); afterBarrier.SignalAndWait(); }); #pragma warning restore 4014 beforeBarrier.SignalAndWait(); Thread.Sleep(100); // wait a little to let the Publish call kick off Expectations.Expect(loggedInUsers) .Not.To.Contain(sam); // we can unsuspend eventAggregator.Unsuspend(); afterBarrier.SignalAndWait(); Expectations.Expect(loggedInUsers) .To.Contain(sam); // there's an async publish which won't block up the publisher: eventAggregator.Suspend(); var task = eventAggregator.GetEvent <LogoutEvent>() .PublishAsync(sam); var waited = task.Wait(100); Expectations.Expect(waited) .To.Be.False(); Expectations.Expect(loggedInUsers) .To.Contain(sam); eventAggregator.Unsuspend(); await task; Expectations.Expect(loggedInUsers) .Not.To.Contain(sam); // when to use Publish vs PublishAsync // - Publish is useful when you'd like to use your event aggregator // from, eg, a WPF application, since handlers will get called // on the same thread (most likely your UI thread, if Publish was // called, eg, from a button click event handler), so you won't have to // marshall to the UI thread. However, you'll still have to consider // what your consumer code is doing to ensure that the UI doesn't // lock up, of course! // Since Publish will BLOCK when the event aggregator (or single event // type) is suspended, it's a bad idea to use Publish from your UI handlers // if you ever plan on suspending pub/sub as suspension will likely cause // your app to hang (UI thread will go unresponsive and you'll get a white // app window // On the other hand, the blocking nature of Publish means that you are // guaranteed of message delivery order // - PublishAsync can be used as "fire and forget" for background // handling, but of course this means that you're not guaranteed of // message delivery order (chances are good they'll come in order, but // this is really up to the TPL and how the task is scheduled) and you'll // have to marshal back to the UI thread if that makes sense for your // application // Naturally, receivers are invoked on the final thread that the publish // happened on -- if you're using PublishAsync, that means it's quite // likely to _not_ be the same thread as the caller // we can also suspend / resume for specific events var logoutEvent = eventAggregator.GetEvent <LogoutEvent>(); logoutEvent.Suspend(); var logoutTask = logoutEvent.PublishAsync(bob); logoutTask.Wait(100); Expectations.Expect(loggedInUsers) .To.Contain(bob); // logout messages were suspended! await loginEvent.PublishAsync(sam); Expectations.Expect(loggedInUsers) .To.Contain(sam); logoutEvent.Unsuspend(); waited = logoutTask.Wait(100); Expectations.Expect(waited) .To.Be.True(); Expectations.Expect(loggedInUsers) .Not.To.Contain(bob); // we can also have limited subscriptions var onceOffUser = null as User; var limitedUsers = new List <User>(); var resubscribe = false; eventAggregator.GetEvent <OnceOffEvent>() .SubscribeOnce(OnceOffSubscription); var limit = RandomValueGen.GetRandomInt(3, 5); eventAggregator.GetEvent <LimitedEvent>() .LimitedSubscription(user => limitedUsers.Add(user), limit); for (var i = 0; i < 10; i++) { eventAggregator.GetEvent <OnceOffEvent>() .Publish(RandomValueGen.GetRandom <User>()); eventAggregator.GetEvent <LimitedEvent>() .Publish(RandomValueGen.GetRandom <User>()); } Expectations.Expect(onceOffUser) .Not.To.Be.Null(); Expectations.Expect(limitedUsers) .To.Contain.Only(limit).Items(); onceOffUser = null; resubscribe = true; eventAggregator.GetEvent <OnceOffEvent>() .SubscribeOnce(OnceOffSubscription); eventAggregator.GetEvent <OnceOffEvent>() .Publish(sam); Expectations.Expect(onceOffUser) .To.Be(sam); // since we should have resubscribed, this publish // will now throw Expectations.Expect(() => eventAggregator.GetEvent <OnceOffEvent>() .Publish(sam) ).To.Throw <InvalidOperationException>(); // Assert void OnceOffSubscription(User user) { if (onceOffUser != null) { throw new InvalidOperationException( $"Once-off subscription should limit to one callback!" ); } onceOffUser = user; // sometimes it's useful to re-subscribe here, depending // on your app requirements (: if (resubscribe) { eventAggregator.GetEvent <OnceOffEvent>() .SubscribeOnce(OnceOffSubscription); } } }