using Azimuth; using System; using UnitTestSharp; namespace Susurrus.UnitTests { public class SoundDefinitionTests : TestFixture { public static Sound Clip(double seconds = 1) { return new Sound(TimeSpan.FromSeconds(seconds), channelCount: 1); } public class CtorTests : TestFixture { public void ManyClips_KeepsEverySettingGiven() { Bus bus = new Bus("Effects"); SoundDefinition definition = new SoundDefinition(new[] { Clip(), Clip() }, bus, baseVolume: 0.5f, priority: 3, maxInstances: 4, minRetriggerSeconds: 0.25f, neverRepeatClip: true); CheckEqual(2, definition.ClipCount); Check(bus == definition.Bus); CheckEqual(0.5f, definition.BaseVolume); CheckEqual(3, definition.Priority); CheckEqual(4, definition.MaxInstances); CheckEqual(0.25f, definition.MinRetriggerSeconds); CheckTrue(definition.NeverRepeatClip); } public void Defaults_AreFullVolumeNoCapNoIntervalAndRepeatsAllowed() { SoundDefinition definition = new SoundDefinition(new[] { Clip() }, new Bus("Effects")); CheckEqual(1f, definition.BaseVolume); CheckEqual(0, definition.Priority); CheckEqual(SoundDefinition.Unlimited, definition.MaxInstances); CheckEqual(0f, definition.MinRetriggerSeconds); CheckFalse(definition.NeverRepeatClip); } public void OneClip_MakesADefinitionOfThatClip() { Sound clip = Clip(); SoundDefinition definition = new SoundDefinition(clip, new Bus("Effects"), priority: 2); CheckEqual(1, definition.ClipCount); Check(clip == definition.ClipAt(0)); CheckEqual(2, definition.Priority); CheckFalse(definition.NeverRepeatClip); } public void ChangingTheListAfterwards_ChangesNothing() { Sound first = Clip(); Sound[] clips = { first, Clip() }; SoundDefinition definition = new SoundDefinition(clips, new Bus("Effects")); clips[0] = Clip(); Check(first == definition.ClipAt(0)); } public void ManyClips_KeepsTheVariationsGiven() { SoundDefinition definition = new SoundDefinition(new[] { Clip() }, new Bus("Effects"), volumeDecibels: new Variation(-6, 0), pitchSemitones: new Variation(-1, 2)); CheckEqual(-6.0, definition.VolumeDecibels.Minimum.Value); CheckEqual(0.0, definition.VolumeDecibels.Maximum.Value); CheckEqual(-1.0, definition.PitchSemitones.Minimum.Value); CheckEqual(2.0, definition.PitchSemitones.Maximum.Value); } public void OneClip_KeepsTheVariationsGiven() { SoundDefinition definition = new SoundDefinition(Clip(), new Bus("Effects"), volumeDecibels: new Variation(-6, 0), pitchSemitones: new Variation(-1, 2)); CheckEqual(-6.0, definition.VolumeDecibels.Minimum.Value); CheckEqual(2.0, definition.PitchSemitones.Maximum.Value); } public void ByDefault_HasNoVariation() { SoundDefinition definition = new SoundDefinition(Clip(), new Bus("Effects")); CheckTrue(definition.VolumeDecibels.IsEmpty); CheckTrue(definition.PitchSemitones.IsEmpty); } public void ManyClips_KeepsTheFalloffGiven() { SoundDefinition definition = new SoundDefinition(new[] { Clip() }, new Bus("Effects"), falloff: new Falloff(2, 10)); CheckEqual(0.5f, definition.Falloff.GainAt(6)); } public void OneClip_KeepsTheFalloffGiven() { SoundDefinition definition = new SoundDefinition(Clip(), new Bus("Effects"), falloff: new Falloff(2, 10)); CheckEqual(0.5f, definition.Falloff.GainAt(6)); } public void ACustomFalloff_IsKeptAsItIs() { IFalloff custom = new Falloff(2, 10); SoundDefinition definition = new SoundDefinition(Clip(), new Bus("Effects"), falloff: custom); CheckTrue(ReferenceEquals(custom, definition.Falloff)); } public void OneClip_KeepsTheLoopGiven() { SoundDefinition definition = new SoundDefinition(Clip(), new Bus("Effects"), loop: Loop.Whole); CheckTrue(definition.Loop.IsLooping); } public void ManyClips_KeepTheLoopGiven() { SoundDefinition definition = new SoundDefinition(new[] { Clip(), Clip() }, new Bus("Effects"), loop: new Loop(TimeSpan.FromSeconds(0.25))); CheckEqual(TimeSpan.FromSeconds(0.25), definition.Loop.Start); } public void ByDefault_DoesNotLoop() { CheckFalse(new SoundDefinition(Clip(), new Bus("Effects")).Loop.IsLooping); } public void ALoopPastTheEndOfAClip_Throws() { CheckThrow(typeof(ArgumentOutOfRangeException)); new SoundDefinition(Clip(), new Bus("Effects"), loop: new Loop(TimeSpan.Zero, TimeSpan.FromSeconds(9))); } public void ALoopThatFitsOnlyTheLongerClip_Throws() { Sound shorter = new Sound(TimeSpan.FromSeconds(1), channelCount: 1); Sound longer = new Sound(TimeSpan.FromSeconds(4), channelCount: 1); CheckThrow(typeof(ArgumentOutOfRangeException)); new SoundDefinition(new[] { longer, shorter }, new Bus("Effects"), loop: new Loop(TimeSpan.FromSeconds(2))); } public void ByDefault_HasNoFalloff() { SoundDefinition definition = new SoundDefinition(Clip(), new Bus("Effects")); CheckEqual(1f, definition.Falloff.GainAt(1e9)); } public void APitchVariationPastTheLowestPitch_Throws() { CheckThrow(typeof(ArgumentOutOfRangeException)); new SoundDefinition(Clip(), new Bus("Effects"), pitchSemitones: new Variation(-121, 0)); } public void APitchVariationPastTheHighestPitch_Throws() { CheckThrow(typeof(ArgumentOutOfRangeException)); new SoundDefinition(Clip(), new Bus("Effects"), pitchSemitones: new Variation(0, 121)); } public void APitchVariationToTheLimits_IsAllowed() { SoundDefinition definition = new SoundDefinition(Clip(), new Bus("Effects"), pitchSemitones: new Variation(-Pitch.MaxSemitones, Pitch.MaxSemitones)); CheckEqual((double)Pitch.MaxSemitones, definition.PitchSemitones.Maximum.Value); } public void NullClips_Throws() { CheckThrow(typeof(ArgumentNullException)); new SoundDefinition((Sound[])null, new Bus("Effects")); } public void NoClips_Throws() { CheckThrow(typeof(ArgumentException)); new SoundDefinition(new Sound[0], new Bus("Effects")); } public void ANullClip_Throws() { CheckThrow(typeof(ArgumentException)); new SoundDefinition(new Sound[] { Clip(), null }, new Bus("Effects")); } public void ANullBus_Throws() { CheckThrow(typeof(ArgumentNullException)); new SoundDefinition(new[] { Clip() }, null); } public void ANegativeBaseVolume_Throws() { CheckThrow(typeof(ArgumentOutOfRangeException)); new SoundDefinition(new[] { Clip() }, new Bus("Effects"), baseVolume: -1f); } public void ACapOfZero_Throws() { CheckThrow(typeof(ArgumentOutOfRangeException)); new SoundDefinition(new[] { Clip() }, new Bus("Effects"), maxInstances: 0); } public void ANegativeInterval_Throws() { CheckThrow(typeof(ArgumentOutOfRangeException)); new SoundDefinition(new[] { Clip() }, new Bus("Effects"), minRetriggerSeconds: -0.1f); } public void AnIntervalThatIsNotANumber_Throws() { CheckThrow(typeof(ArgumentOutOfRangeException)); new SoundDefinition(new[] { Clip() }, new Bus("Effects"), minRetriggerSeconds: float.NaN); } public void AnInfiniteInterval_Throws() { CheckThrow(typeof(ArgumentOutOfRangeException)); new SoundDefinition(new[] { Clip() }, new Bus("Effects"), minRetriggerSeconds: float.PositiveInfinity); } public void OneClip_KeepsTheFadesGiven() { SoundDefinition definition = new SoundDefinition(Clip(), new Bus("Music"), fadeInSeconds: 1.5f, fadeOutSeconds: 2f); CheckEqual(1.5f, definition.FadeInSeconds); CheckEqual(2f, definition.FadeOutSeconds); } public void ManyClips_KeepTheFadesGiven() { SoundDefinition definition = new SoundDefinition(new[] { Clip(), Clip() }, new Bus("Music"), fadeInSeconds: 1.5f, fadeOutSeconds: 2f); CheckEqual(1.5f, definition.FadeInSeconds); CheckEqual(2f, definition.FadeOutSeconds); } public void ByDefault_HasNoFadeInAndLeavesTheFadeOutToTheMixer() { SoundDefinition definition = new SoundDefinition(Clip(), new Bus("Effects")); CheckEqual(0f, definition.FadeInSeconds); CheckNull(definition.FadeOutSeconds); } public void ANegativeFadeIn_Throws() { CheckThrow(typeof(ArgumentOutOfRangeException)); new SoundDefinition(Clip(), new Bus("Music"), fadeInSeconds: -1f); } public void ANonFiniteFadeIn_Throws() { CheckThrow(typeof(ArgumentOutOfRangeException)); new SoundDefinition(Clip(), new Bus("Music"), fadeInSeconds: float.NaN); } public void ANegativeFadeOut_Throws() { CheckThrow(typeof(ArgumentOutOfRangeException)); new SoundDefinition(Clip(), new Bus("Music"), fadeOutSeconds: -1f); } public void AnInfiniteFadeOut_Throws() { CheckThrow(typeof(ArgumentOutOfRangeException)); new SoundDefinition(Clip(), new Bus("Music"), fadeOutSeconds: float.PositiveInfinity); } public void OneClip_KeepsTheSustainGraceGiven() { CheckEqual(0.4f, new SoundDefinition(Clip(), new Bus("Music"), sustainGraceSeconds: 0.4f) .SustainGraceSeconds); } public void ManyClips_KeepTheSustainGraceGiven() { SoundDefinition definition = new SoundDefinition(new[] { Clip(), Clip() }, new Bus("Music"), sustainGraceSeconds: 0.4f); CheckEqual(0.4f, definition.SustainGraceSeconds); } public void ByDefault_HasTheDefaultSustainGrace() { CheckEqual(SoundDefinition.DefaultSustainGraceSeconds, new SoundDefinition(Clip(), new Bus("Effects")).SustainGraceSeconds); } public void ANegativeSustainGrace_Throws() { CheckThrow(typeof(ArgumentOutOfRangeException)); new SoundDefinition(Clip(), new Bus("Music"), sustainGraceSeconds: -1f); } public void ANotANumberSustainGrace_Throws() { CheckThrow(typeof(ArgumentOutOfRangeException)); new SoundDefinition(Clip(), new Bus("Music"), sustainGraceSeconds: float.NaN); } } public class ClipAtTests : TestFixture { public void ReturnsTheClipAtThatPosition() { Sound first = Clip(); Sound second = Clip(); SoundDefinition definition = new SoundDefinition(new[] { first, second }, new Bus("Effects")); Check(first == definition.ClipAt(0)); Check(second == definition.ClipAt(1)); } public void APositionPastTheEnd_Throws() { SoundDefinition definition = new SoundDefinition(new[] { Clip() }, new Bus("Effects")); CheckThrow(typeof(ArgumentOutOfRangeException)); definition.ClipAt(1); } public void ANegativePosition_Throws() { SoundDefinition definition = new SoundDefinition(new[] { Clip() }, new Bus("Effects")); CheckThrow(typeof(ArgumentOutOfRangeException)); definition.ClipAt(-1); } } } }