using Amphora; using System; using UnitTestSharp; using static Susurrus.UnitTests.TestSounds; namespace Susurrus.UnitTests { public class StreamedSoundTests : TestFixture { public static StreamedSound OpenSound() { return new StreamedSound( SoundStreams.Open(new ByteChunks(new ByteView(LoadFixture("Mono441Hz.ogg")))).Value); } public class CtorTests : TestFixture { public void TakesTheDurationFromTheStream() { StreamedSound sound = OpenSound(); CheckEqual(TimeSpan.FromTicks(sound.Stream.FrameCount * TimeSpan.TicksPerSecond / 44100), sound.Duration); } public void TakesTheChannelCountFromTheStream() { CheckEqual(1, OpenSound().ChannelCount); } public void KeepsTheStream() { ISoundStream stream = SoundStreams.Open( new ByteChunks(new ByteView(LoadFixture("Mono441Hz.ogg")))).Value; CheckTrue(ReferenceEquals(stream, new StreamedSound(stream).Stream)); } public void StartsFreeAndOpen() { StreamedSound sound = OpenSound(); CheckFalse(sound.IsHeld); CheckFalse(sound.IsDisposed); } public void NullStream_Throws() { CheckThrow(typeof(ArgumentNullException)); new StreamedSound(null); } } public static StreamedSound CountingSound(int frameCount) { return new StreamedSound(StreamFeedTests.CountingStream(frameCount)); } public class BeginTests : TestFixture { public void HoldsTheSound() { StreamedSound sound = CountingSound(frameCount: 8); CheckTrue(sound.Begin(Loop.None).IsOk); CheckTrue(sound.IsHeld); } public void WhileHeld_Throws() { StreamedSound sound = CountingSound(frameCount: 8); sound.Begin(Loop.None); CheckThrow(typeof(InvalidOperationException)); sound.Begin(Loop.None); } public void KeepsTheLoop() { StreamedSound sound = CountingSound(frameCount: 8); sound.Begin(Loop.Whole); CheckTrue(sound.Loop.IsLooping); } public void MovesTheStreamBackToItsStart() { StreamedSound sound = CountingSound(frameCount: 8); sound.Stream.Seek(5); sound.Begin(Loop.None); CheckEqual(0L, sound.Stream.Position); } public void StartsNotFed() { StreamedSound sound = CountingSound(frameCount: 8); sound.Begin(Loop.None); sound.Feed(new ByteView(new byte[100])); sound.Release(); sound.Begin(Loop.None); CheckFalse(sound.IsFed); } public void ASeekThatFails_FailsAndMarksTheSoundFed() { StreamFeedTests.FlakyStream stream = new StreamFeedTests.FlakyStream(StreamFeedTests.CountingStream(8)); stream.Seek(5); stream.FailSeeks = true; StreamedSound sound = new StreamedSound(stream); Status status = sound.Begin(Loop.None); CheckEqual(SoundFailures.StreamRequestInvalid, status.Kind); CheckTrue(sound.IsFed); CheckTrue(sound.IsHeld); } } public class FeedTests : TestFixture { public void ADestinationTheSoundFills_LeavesItNotFed() { StreamedSound sound = CountingSound(frameCount: 8); sound.Begin(Loop.None); CheckEqual(4, sound.Feed(new ByteView(new byte[8])).Value); CheckFalse(sound.IsFed); } public void ADestinationLargerThanWhatIsLeft_FeedsTheSound() { StreamedSound sound = CountingSound(frameCount: 8); sound.Begin(Loop.None); CheckEqual(8, sound.Feed(new ByteView(new byte[40])).Value); CheckTrue(sound.IsFed); } public void ALoopingSound_NeverGetsFed() { StreamedSound sound = CountingSound(frameCount: 3); sound.Begin(Loop.Whole); CheckEqual(20, sound.Feed(new ByteView(new byte[40])).Value); CheckFalse(sound.IsFed); } public void AReadThatFails_FailsAndFeedsTheSound() { StreamFeedTests.FlakyStream stream = new StreamFeedTests.FlakyStream(StreamFeedTests.CountingStream(8)); stream.FailReads = true; StreamedSound sound = new StreamedSound(stream); sound.Begin(Loop.None); StatusOr result = sound.Feed(new ByteView(new byte[8])); CheckEqual(SoundFailures.StreamRequestInvalid, result.Status.Kind); CheckTrue(sound.IsFed); } } public class HoldTests : TestFixture { public void MarksTheSoundHeld() { StreamedSound sound = OpenSound(); sound.Hold(); CheckTrue(sound.IsHeld); } public void WhileHeld_Throws() { StreamedSound sound = OpenSound(); sound.Hold(); CheckThrow(typeof(InvalidOperationException)); sound.Hold(); } public void AfterDispose_Throws() { StreamedSound sound = OpenSound(); sound.Dispose(); CheckThrow(typeof(ObjectDisposedException)); sound.Hold(); } } public class ReleaseTests : TestFixture { public void FreesTheSoundToBeHeldAgain() { StreamedSound sound = OpenSound(); sound.Hold(); sound.Release(); sound.Hold(); CheckTrue(sound.IsHeld); } public void WithoutAHold_Throws() { CheckThrow(typeof(InvalidOperationException)); OpenSound().Release(); } } public class DisposeTests : TestFixture { public void ClosesTheStream() { StreamedSound sound = OpenSound(); sound.Dispose(); CheckTrue(sound.IsDisposed); CheckEqual(SoundFailures.StreamRequestInvalid, sound.Stream.Seek(0).Kind); } public void CanBeCalledTwice() { StreamedSound sound = OpenSound(); sound.Dispose(); sound.Dispose(); CheckTrue(sound.IsDisposed); } public void WhileHeld_Throws() { StreamedSound sound = OpenSound(); sound.Hold(); CheckThrow(typeof(InvalidOperationException)); sound.Dispose(); } public void WhileHeld_LeavesTheStreamOpen() { StreamedSound sound = OpenSound(); sound.Hold(); try { sound.Dispose(); } catch (InvalidOperationException) { } CheckFalse(sound.IsDisposed); CheckTrue(sound.Stream.Seek(0).IsOk); } } } }