diff --git a/CHANGELOG.md b/CHANGELOG.md index edf8529a..1ec332c8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,17 @@ # Release History +## 2.0.0-beta.9 (Unreleased) + +### Features Added + +- Added `OpenAIAudioModelFactory`, `OpenAIEmbeddingsModelFactory`, and `OpenAIImagesModelFactory` static classes to the `Audio`, `Embeddings`, and `Images` namespaces, respectively. Model factories can be used to instantiate OpenAI models for mocking in non-live test scenarios. + +### Breaking Changes + +### Bugs Fixed + +### Other Changes + ## 2.0.0-beta.8 (2024-07-31) ### Breaking Changes diff --git a/src/Custom/Audio/OpenAIAudioModelFactory.cs b/src/Custom/Audio/OpenAIAudioModelFactory.cs new file mode 100644 index 00000000..636b7768 --- /dev/null +++ b/src/Custom/Audio/OpenAIAudioModelFactory.cs @@ -0,0 +1,72 @@ +using System; +using System.Collections.Generic; +using System.Linq; + +namespace OpenAI.Audio; + +/// Model factory for models. +public static partial class OpenAIAudioModelFactory +{ + /// Initializes a new instance of . + /// A new instance for mocking. + public static AudioTranscription AudioTranscription(string language = null, TimeSpan? duration = null, string text = null, IEnumerable words = null, IEnumerable segments = null) + { + words ??= new List(); + segments ??= new List(); + + return new AudioTranscription( + InternalCreateTranscriptionResponseVerboseJsonTask.Transcribe, + language, + duration, + text, + words.ToList(), + segments.ToList(), + serializedAdditionalRawData: null); + } + + /// Initializes a new instance of . + /// A new instance for mocking. + public static AudioTranslation AudioTranslation(string language = null, TimeSpan? duration = null, string text = null, IEnumerable segments = null) + { + segments ??= new List(); + + return new AudioTranslation( + InternalCreateTranslationResponseVerboseJsonTask.Translate, + language, + duration, + text, + segments.ToList(), + serializedAdditionalRawData: null); + } + + /// Initializes a new instance of . + /// A new instance for mocking. + public static TranscribedSegment TranscribedSegment(int id = default, long seekOffset = default, TimeSpan start = default, TimeSpan end = default, string text = null, IEnumerable tokenIds = null, float temperature = default, double averageLogProbability = default, float compressionRatio = default, double noSpeechProbability = default) + { + tokenIds ??= new List(); + + return new TranscribedSegment( + id, + seekOffset, + start, + end, + text, + tokenIds.ToList(), + temperature, + averageLogProbability, + compressionRatio, + noSpeechProbability, + serializedAdditionalRawData: null); + } + + /// Initializes a new instance of . + /// A new instance for mocking. + public static TranscribedWord TranscribedWord(string word = null, TimeSpan start = default, TimeSpan end = default) + { + return new TranscribedWord( + word, + start, + end, + serializedAdditionalRawData: null); + } +} diff --git a/src/Custom/Embeddings/Embedding.cs b/src/Custom/Embeddings/Embedding.cs index 720057e4..bc21ad73 100644 --- a/src/Custom/Embeddings/Embedding.cs +++ b/src/Custom/Embeddings/Embedding.cs @@ -83,6 +83,16 @@ internal Embedding(int index, BinaryData embeddingProperty, InternalEmbeddingObj Vector = ConvertToVectorOfFloats(embeddingProperty); } + // CUSTOM: Entirely custom constructor used by the Model Factory. + /// Initializes a new instance of . + /// The index of the embedding in the list of embeddings. + /// The embedding vector, which is a list of floats. + internal Embedding(int index, ReadOnlyMemory vector) + { + Index = index; + Vector = vector; + } + // CUSTOM: Added as a public, custom property. For slightly better performance, the embedding is always requested as a base64-encoded // string and then manually transformed into a more user-friendly ReadOnlyMemory. /// diff --git a/src/Custom/Embeddings/OpenAIEmbeddingsModelFactory.cs b/src/Custom/Embeddings/OpenAIEmbeddingsModelFactory.cs new file mode 100644 index 00000000..ff03606c --- /dev/null +++ b/src/Custom/Embeddings/OpenAIEmbeddingsModelFactory.cs @@ -0,0 +1,43 @@ +using System.Collections.Generic; +using System.Linq; + +namespace OpenAI.Embeddings; + +/// Model factory for models. +public static partial class OpenAIEmbeddingsModelFactory +{ + /// Initializes a new instance of . + /// A new instance for mocking. + public static Embedding Embedding(int index = default, IEnumerable vector = null) + { + vector ??= new List(); + + return new Embedding( + index, + vector.ToArray()); + } + + /// Initializes a new instance of . + /// A new instance for mocking. + public static EmbeddingCollection EmbeddingCollection(IEnumerable items = null, string model = null, EmbeddingTokenUsage usage = null) + { + items ??= new List(); + + return new EmbeddingCollection( + items.ToList(), + model, + @object: default, + usage, + serializedAdditionalRawData: null); + } + + /// Initializes a new instance of . + /// A new instance for mocking. + public static EmbeddingTokenUsage EmbeddingTokenUsage(int inputTokens = default, int totalTokens = default) + { + return new EmbeddingTokenUsage( + inputTokens, + totalTokens, + serializedAdditionalRawData: null); + } +} diff --git a/src/Custom/Images/OpenAIImagesModelFactory.cs b/src/Custom/Images/OpenAIImagesModelFactory.cs new file mode 100644 index 00000000..c318ff41 --- /dev/null +++ b/src/Custom/Images/OpenAIImagesModelFactory.cs @@ -0,0 +1,32 @@ +using System; +using System.Collections.Generic; +using System.Linq; + +namespace OpenAI.Images; + +/// Model factory for models. +public static partial class OpenAIImagesModelFactory +{ + /// Initializes a new instance of . + /// A new instance for mocking. + public static GeneratedImage GeneratedImage(BinaryData imageBytes = null, Uri imageUri = null, string revisedPrompt = null) + { + return new GeneratedImage( + imageBytes, + imageUri, + revisedPrompt, + serializedAdditionalRawData: null); + } + + /// Initializes a new instance of . + /// A new instance for mocking. + public static GeneratedImageCollection GeneratedImageCollection(DateTimeOffset createdAt = default, IEnumerable items = null) + { + items ??= new List(); + + return new GeneratedImageCollection( + createdAt, + items.ToList(), + serializedAdditionalRawData: null); + } +} diff --git a/tests/Audio/OpenAIAudioModelFactoryTests.cs b/tests/Audio/OpenAIAudioModelFactoryTests.cs new file mode 100644 index 00000000..717509f3 --- /dev/null +++ b/tests/Audio/OpenAIAudioModelFactoryTests.cs @@ -0,0 +1,397 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using NUnit.Framework; +using OpenAI.Audio; + +namespace OpenAI.Tests.Audio; + +[Parallelizable(ParallelScope.All)] +[Category("Smoke")] +public partial class OpenAIAudioModelFactoryTests +{ + [Test] + public void AudioTranscriptionWithNoPropertiesWorks() + { + AudioTranscription audioTranscription = OpenAIAudioModelFactory.AudioTranscription(); + + Assert.That(audioTranscription.Language, Is.Null); + Assert.That(audioTranscription.Duration, Is.Null); + Assert.That(audioTranscription.Text, Is.Null); + Assert.That(audioTranscription.Words, Is.Not.Null.And.Empty); + Assert.That(audioTranscription.Segments, Is.Not.Null.And.Empty); + } + + [Test] + public void AudioTranscriptionWithLanguageWorks() + { + string language = "esperanto"; + AudioTranscription audioTranscription = OpenAIAudioModelFactory.AudioTranscription(language: language); + + Assert.That(audioTranscription.Language, Is.EqualTo(language)); + Assert.That(audioTranscription.Duration, Is.Null); + Assert.That(audioTranscription.Text, Is.Null); + Assert.That(audioTranscription.Words, Is.Not.Null.And.Empty); + Assert.That(audioTranscription.Segments, Is.Not.Null.And.Empty); + } + + [Test] + public void AudioTranscriptionWithDurationWorks() + { + TimeSpan duration = TimeSpan.FromSeconds(45); + AudioTranscription audioTranscription = OpenAIAudioModelFactory.AudioTranscription(duration: duration); + + Assert.That(audioTranscription.Language, Is.Null); + Assert.That(audioTranscription.Duration, Is.EqualTo(duration)); + Assert.That(audioTranscription.Text, Is.Null); + Assert.That(audioTranscription.Words, Is.Not.Null.And.Empty); + Assert.That(audioTranscription.Segments, Is.Not.Null.And.Empty); + } + + [Test] + public void AudioTranscriptionWithTextWorks() + { + string text = "I've been transcripted."; + AudioTranscription audioTranscription = OpenAIAudioModelFactory.AudioTranscription(text: text); + + Assert.That(audioTranscription.Language, Is.Null); + Assert.That(audioTranscription.Duration, Is.Null); + Assert.That(audioTranscription.Text, Is.EqualTo(text)); + Assert.That(audioTranscription.Words, Is.Not.Null.And.Empty); + Assert.That(audioTranscription.Segments, Is.Not.Null.And.Empty); + } + + [Test] + public void AudioTranscriptionWithWordsWorks() + { + IEnumerable words = [ + OpenAIAudioModelFactory.TranscribedWord(word: "Apple"), + OpenAIAudioModelFactory.TranscribedWord(word: "pie") + ]; + AudioTranscription audioTranscription = OpenAIAudioModelFactory.AudioTranscription(words: words); + + Assert.That(audioTranscription.Language, Is.Null); + Assert.That(audioTranscription.Duration, Is.Null); + Assert.That(audioTranscription.Text, Is.Null); + Assert.That(audioTranscription.Words.SequenceEqual(words), Is.True); + Assert.That(audioTranscription.Segments, Is.Not.Null.And.Empty); + } + + [Test] + public void AudioTranscriptionWithSegmentsWorks() + { + IEnumerable segments = [ + OpenAIAudioModelFactory.TranscribedSegment(id: 1), + OpenAIAudioModelFactory.TranscribedSegment(id: 2) + ]; + AudioTranscription audioTranscription = OpenAIAudioModelFactory.AudioTranscription(segments: segments); + + Assert.That(audioTranscription.Language, Is.Null); + Assert.That(audioTranscription.Duration, Is.Null); + Assert.That(audioTranscription.Text, Is.Null); + Assert.That(audioTranscription.Words, Is.Not.Null.And.Empty); + Assert.That(audioTranscription.Segments.SequenceEqual(segments), Is.True); + } + + [Test] + public void AudioTranslationWithNoPropertiesWorks() + { + AudioTranslation audioTranslation = OpenAIAudioModelFactory.AudioTranslation(); + + Assert.That(audioTranslation.Language, Is.Null); + Assert.That(audioTranslation.Duration, Is.Null); + Assert.That(audioTranslation.Text, Is.Null); + Assert.That(audioTranslation.Segments, Is.Not.Null.And.Empty); + } + + [Test] + public void AudioTranslationWithLanguageWorks() + { + string language = "esperanto"; + AudioTranslation audioTranslation = OpenAIAudioModelFactory.AudioTranslation(language: language); + + Assert.That(audioTranslation.Language, Is.EqualTo(language)); + Assert.That(audioTranslation.Duration, Is.Null); + Assert.That(audioTranslation.Text, Is.Null); + Assert.That(audioTranslation.Segments, Is.Not.Null.And.Empty); + } + + [Test] + public void AudioTranslationWithDurationWorks() + { + TimeSpan duration = TimeSpan.FromSeconds(45); + AudioTranslation audioTranslation = OpenAIAudioModelFactory.AudioTranslation(duration: duration); + + Assert.That(audioTranslation.Language, Is.Null); + Assert.That(audioTranslation.Duration, Is.EqualTo(duration)); + Assert.That(audioTranslation.Text, Is.Null); + Assert.That(audioTranslation.Segments, Is.Not.Null.And.Empty); + } + + [Test] + public void AudioTranslationWithTextWorks() + { + string text = "I've been transcripted."; + AudioTranslation audioTranslation = OpenAIAudioModelFactory.AudioTranslation(text: text); + + Assert.That(audioTranslation.Language, Is.Null); + Assert.That(audioTranslation.Duration, Is.Null); + Assert.That(audioTranslation.Text, Is.EqualTo(text)); + Assert.That(audioTranslation.Segments, Is.Not.Null.And.Empty); + } + + [Test] + public void AudioTranslationWithSegmentsWorks() + { + IEnumerable segments = [ + OpenAIAudioModelFactory.TranscribedSegment(id: 1), + OpenAIAudioModelFactory.TranscribedSegment(id: 2) + ]; + AudioTranslation audioTranslation = OpenAIAudioModelFactory.AudioTranslation(segments: segments); + + Assert.That(audioTranslation.Language, Is.Null); + Assert.That(audioTranslation.Duration, Is.Null); + Assert.That(audioTranslation.Text, Is.Null); + Assert.That(audioTranslation.Segments.SequenceEqual(segments), Is.True); + } + + [Test] + public void TranscribedSegmentWithNoPropertiesWorks() + { + TranscribedSegment transcribedSegment = OpenAIAudioModelFactory.TranscribedSegment(); + + Assert.That(transcribedSegment.Id, Is.EqualTo(default(int))); + Assert.That(transcribedSegment.SeekOffset, Is.EqualTo(default(long))); + Assert.That(transcribedSegment.Start, Is.EqualTo(default(TimeSpan))); + Assert.That(transcribedSegment.End, Is.EqualTo(default(TimeSpan))); + Assert.That(transcribedSegment.Text, Is.Null); + Assert.That(transcribedSegment.TokenIds, Is.Not.Null.And.Empty); + Assert.That(transcribedSegment.Temperature, Is.EqualTo(default(float))); + Assert.That(transcribedSegment.AverageLogProbability, Is.EqualTo(default(double))); + Assert.That(transcribedSegment.CompressionRatio, Is.EqualTo(default(float))); + Assert.That(transcribedSegment.NoSpeechProbability, Is.EqualTo(default(double))); + } + + [Test] + public void TranscribedSegmentWithIdWorks() + { + int id = 10; + TranscribedSegment transcribedSegment = OpenAIAudioModelFactory.TranscribedSegment(id: id); + + Assert.That(transcribedSegment.Id, Is.EqualTo(id)); + Assert.That(transcribedSegment.SeekOffset, Is.EqualTo(default(long))); + Assert.That(transcribedSegment.Start, Is.EqualTo(default(TimeSpan))); + Assert.That(transcribedSegment.End, Is.EqualTo(default(TimeSpan))); + Assert.That(transcribedSegment.Text, Is.Null); + Assert.That(transcribedSegment.TokenIds, Is.Not.Null.And.Empty); + Assert.That(transcribedSegment.Temperature, Is.EqualTo(default(float))); + Assert.That(transcribedSegment.AverageLogProbability, Is.EqualTo(default(double))); + Assert.That(transcribedSegment.CompressionRatio, Is.EqualTo(default(float))); + Assert.That(transcribedSegment.NoSpeechProbability, Is.EqualTo(default(double))); + } + + [Test] + public void TranscribedSegmentWithSeekOffsetWorks() + { + long seekOffset = 9000000000; + TranscribedSegment transcribedSegment = OpenAIAudioModelFactory.TranscribedSegment(seekOffset: seekOffset); + + Assert.That(transcribedSegment.Id, Is.EqualTo(default(int))); + Assert.That(transcribedSegment.SeekOffset, Is.EqualTo(seekOffset)); + Assert.That(transcribedSegment.Start, Is.EqualTo(default(TimeSpan))); + Assert.That(transcribedSegment.End, Is.EqualTo(default(TimeSpan))); + Assert.That(transcribedSegment.Text, Is.Null); + Assert.That(transcribedSegment.TokenIds, Is.Not.Null.And.Empty); + Assert.That(transcribedSegment.Temperature, Is.EqualTo(default(float))); + Assert.That(transcribedSegment.AverageLogProbability, Is.EqualTo(default(double))); + Assert.That(transcribedSegment.CompressionRatio, Is.EqualTo(default(float))); + Assert.That(transcribedSegment.NoSpeechProbability, Is.EqualTo(default(double))); + } + + [Test] + public void TranscribedSegmentWithStartWorks() + { + TimeSpan start = TimeSpan.FromSeconds(45); + TranscribedSegment transcribedSegment = OpenAIAudioModelFactory.TranscribedSegment(start: start); + + Assert.That(transcribedSegment.Id, Is.EqualTo(default(int))); + Assert.That(transcribedSegment.SeekOffset, Is.EqualTo(default(long))); + Assert.That(transcribedSegment.Start, Is.EqualTo(start)); + Assert.That(transcribedSegment.End, Is.EqualTo(default(TimeSpan))); + Assert.That(transcribedSegment.Text, Is.Null); + Assert.That(transcribedSegment.TokenIds, Is.Not.Null.And.Empty); + Assert.That(transcribedSegment.Temperature, Is.EqualTo(default(float))); + Assert.That(transcribedSegment.AverageLogProbability, Is.EqualTo(default(double))); + Assert.That(transcribedSegment.CompressionRatio, Is.EqualTo(default(float))); + Assert.That(transcribedSegment.NoSpeechProbability, Is.EqualTo(default(double))); + } + + [Test] + public void TranscribedSegmentWithEndWorks() + { + TimeSpan end = TimeSpan.FromSeconds(45); + TranscribedSegment transcribedSegment = OpenAIAudioModelFactory.TranscribedSegment(end: end); + + Assert.That(transcribedSegment.Id, Is.EqualTo(default(int))); + Assert.That(transcribedSegment.SeekOffset, Is.EqualTo(default(long))); + Assert.That(transcribedSegment.Start, Is.EqualTo(default(TimeSpan))); + Assert.That(transcribedSegment.End, Is.EqualTo(end)); + Assert.That(transcribedSegment.Text, Is.Null); + Assert.That(transcribedSegment.TokenIds, Is.Not.Null.And.Empty); + Assert.That(transcribedSegment.Temperature, Is.EqualTo(default(float))); + Assert.That(transcribedSegment.AverageLogProbability, Is.EqualTo(default(double))); + Assert.That(transcribedSegment.CompressionRatio, Is.EqualTo(default(float))); + Assert.That(transcribedSegment.NoSpeechProbability, Is.EqualTo(default(double))); + } + + [Test] + public void TranscribedSegmentWithTextWorks() + { + string text = "A segment text"; + TranscribedSegment transcribedSegment = OpenAIAudioModelFactory.TranscribedSegment(text: text); + + Assert.That(transcribedSegment.Id, Is.EqualTo(default(int))); + Assert.That(transcribedSegment.SeekOffset, Is.EqualTo(default(long))); + Assert.That(transcribedSegment.Start, Is.EqualTo(default(TimeSpan))); + Assert.That(transcribedSegment.End, Is.EqualTo(default(TimeSpan))); + Assert.That(transcribedSegment.Text, Is.EqualTo(text)); + Assert.That(transcribedSegment.TokenIds, Is.Not.Null.And.Empty); + Assert.That(transcribedSegment.Temperature, Is.EqualTo(default(float))); + Assert.That(transcribedSegment.AverageLogProbability, Is.EqualTo(default(double))); + Assert.That(transcribedSegment.CompressionRatio, Is.EqualTo(default(float))); + Assert.That(transcribedSegment.NoSpeechProbability, Is.EqualTo(default(double))); + } + + [Test] + public void TranscribedSegmentWithTokenIdsWorks() + { + IEnumerable tokenIds = [ 9000000000, 9000000010 ]; + TranscribedSegment transcribedSegment = OpenAIAudioModelFactory.TranscribedSegment(tokenIds: tokenIds); + + Assert.That(transcribedSegment.Id, Is.EqualTo(default(int))); + Assert.That(transcribedSegment.SeekOffset, Is.EqualTo(default(long))); + Assert.That(transcribedSegment.Start, Is.EqualTo(default(TimeSpan))); + Assert.That(transcribedSegment.End, Is.EqualTo(default(TimeSpan))); + Assert.That(transcribedSegment.Text, Is.Null); + Assert.That(transcribedSegment.TokenIds.SequenceEqual(tokenIds), Is.True); + Assert.That(transcribedSegment.Temperature, Is.EqualTo(default(float))); + Assert.That(transcribedSegment.AverageLogProbability, Is.EqualTo(default(double))); + Assert.That(transcribedSegment.CompressionRatio, Is.EqualTo(default(float))); + Assert.That(transcribedSegment.NoSpeechProbability, Is.EqualTo(default(double))); + } + + [Test] + public void TranscribedSegmentWithTemperatureWorks() + { + float temperature = 0.232f; + TranscribedSegment transcribedSegment = OpenAIAudioModelFactory.TranscribedSegment(temperature: temperature); + + Assert.That(transcribedSegment.Id, Is.EqualTo(default(int))); + Assert.That(transcribedSegment.SeekOffset, Is.EqualTo(default(long))); + Assert.That(transcribedSegment.Start, Is.EqualTo(default(TimeSpan))); + Assert.That(transcribedSegment.End, Is.EqualTo(default(TimeSpan))); + Assert.That(transcribedSegment.Text, Is.Null); + Assert.That(transcribedSegment.TokenIds, Is.Not.Null.And.Empty); + Assert.That(transcribedSegment.Temperature, Is.EqualTo(temperature)); + Assert.That(transcribedSegment.AverageLogProbability, Is.EqualTo(default(double))); + Assert.That(transcribedSegment.CompressionRatio, Is.EqualTo(default(float))); + Assert.That(transcribedSegment.NoSpeechProbability, Is.EqualTo(default(double))); + } + + [Test] + public void TranscribedSegmentWithAverageLogProbabilityWorks() + { + double averageLogProbability = -3.1415; + TranscribedSegment transcribedSegment = OpenAIAudioModelFactory.TranscribedSegment(averageLogProbability: averageLogProbability); + + Assert.That(transcribedSegment.Id, Is.EqualTo(default(int))); + Assert.That(transcribedSegment.SeekOffset, Is.EqualTo(default(long))); + Assert.That(transcribedSegment.Start, Is.EqualTo(default(TimeSpan))); + Assert.That(transcribedSegment.End, Is.EqualTo(default(TimeSpan))); + Assert.That(transcribedSegment.Text, Is.Null); + Assert.That(transcribedSegment.TokenIds, Is.Not.Null.And.Empty); + Assert.That(transcribedSegment.Temperature, Is.EqualTo(default(float))); + Assert.That(transcribedSegment.AverageLogProbability, Is.EqualTo(averageLogProbability)); + Assert.That(transcribedSegment.CompressionRatio, Is.EqualTo(default(float))); + Assert.That(transcribedSegment.NoSpeechProbability, Is.EqualTo(default(double))); + } + + [Test] + public void TranscribedSegmentWithCompressionRatioWorks() + { + float compressionRatio = 1.33f; + TranscribedSegment transcribedSegment = OpenAIAudioModelFactory.TranscribedSegment(compressionRatio: compressionRatio); + + Assert.That(transcribedSegment.Id, Is.EqualTo(default(int))); + Assert.That(transcribedSegment.SeekOffset, Is.EqualTo(default(long))); + Assert.That(transcribedSegment.Start, Is.EqualTo(default(TimeSpan))); + Assert.That(transcribedSegment.End, Is.EqualTo(default(TimeSpan))); + Assert.That(transcribedSegment.Text, Is.Null); + Assert.That(transcribedSegment.TokenIds, Is.Not.Null.And.Empty); + Assert.That(transcribedSegment.Temperature, Is.EqualTo(default(float))); + Assert.That(transcribedSegment.AverageLogProbability, Is.EqualTo(default(double))); + Assert.That(transcribedSegment.CompressionRatio, Is.EqualTo(compressionRatio)); + Assert.That(transcribedSegment.NoSpeechProbability, Is.EqualTo(default(double))); + } + + [Test] + public void TranscribedSegmentWithNoSpeechProbabilityWorks() + { + double noSpeechProbability = 0.02; + TranscribedSegment transcribedSegment = OpenAIAudioModelFactory.TranscribedSegment(noSpeechProbability: noSpeechProbability); + + Assert.That(transcribedSegment.Id, Is.EqualTo(default(int))); + Assert.That(transcribedSegment.SeekOffset, Is.EqualTo(default(long))); + Assert.That(transcribedSegment.Start, Is.EqualTo(default(TimeSpan))); + Assert.That(transcribedSegment.End, Is.EqualTo(default(TimeSpan))); + Assert.That(transcribedSegment.Text, Is.Null); + Assert.That(transcribedSegment.TokenIds, Is.Not.Null.And.Empty); + Assert.That(transcribedSegment.Temperature, Is.EqualTo(default(float))); + Assert.That(transcribedSegment.AverageLogProbability, Is.EqualTo(default(double))); + Assert.That(transcribedSegment.CompressionRatio, Is.EqualTo(default(float))); + Assert.That(transcribedSegment.NoSpeechProbability, Is.EqualTo(noSpeechProbability)); + } + + [Test] + public void TranscribedWordWithNoPropertiesWorks() + { + TranscribedWord transcribedWord = OpenAIAudioModelFactory.TranscribedWord(); + + Assert.That(transcribedWord.Word, Is.Null); + Assert.That(transcribedWord.Start, Is.EqualTo(default(TimeSpan))); + Assert.That(transcribedWord.End, Is.EqualTo(default(TimeSpan))); + } + + [Test] + public void TranscribedWordWithIdWorks() + { + string word = "croissant"; + TranscribedWord transcribedWord = OpenAIAudioModelFactory.TranscribedWord(word: word); + + Assert.That(transcribedWord.Word, Is.EqualTo(word)); + Assert.That(transcribedWord.Start, Is.EqualTo(default(TimeSpan))); + Assert.That(transcribedWord.End, Is.EqualTo(default(TimeSpan))); + } + + [Test] + public void TranscribedWordWithStartWorks() + { + TimeSpan start = TimeSpan.FromSeconds(45); + TranscribedWord transcribedWord = OpenAIAudioModelFactory.TranscribedWord(start: start); + + Assert.That(transcribedWord.Word, Is.Null); + Assert.That(transcribedWord.Start, Is.EqualTo(start)); + Assert.That(transcribedWord.End, Is.EqualTo(default(TimeSpan))); + } + + [Test] + public void TranscribedWordWithEndWorks() + { + TimeSpan end = TimeSpan.FromSeconds(45); + TranscribedWord transcribedWord = OpenAIAudioModelFactory.TranscribedWord(end: end); + + Assert.That(transcribedWord.Word, Is.Null); + Assert.That(transcribedWord.Start, Is.EqualTo(default(TimeSpan))); + Assert.That(transcribedWord.End, Is.EqualTo(end)); + } +} diff --git a/tests/Embeddings/OpenAIEmbeddingsModelFactoryTests.cs b/tests/Embeddings/OpenAIEmbeddingsModelFactoryTests.cs new file mode 100644 index 00000000..7de4d354 --- /dev/null +++ b/tests/Embeddings/OpenAIEmbeddingsModelFactoryTests.cs @@ -0,0 +1,116 @@ +using System.Collections.Generic; +using System.Linq; +using NUnit.Framework; +using OpenAI.Embeddings; + +namespace OpenAI.Tests.Embeddings +{ + [Parallelizable(ParallelScope.All)] + [Category("Smoke")] + public partial class OpenAIEmbeddingsModelFactoryTests + { + [Test] + public void EmbeddingWithNoPropertiesWorks() + { + Embedding embedding = OpenAIEmbeddingsModelFactory.Embedding(); + + Assert.That(embedding.Index, Is.EqualTo(default(int))); + Assert.That(embedding.Vector.ToArray(), Is.Not.Null.And.Empty); + } + + [Test] + public void EmbeddingWithIndexWorks() + { + int index = 10; + Embedding embedding = OpenAIEmbeddingsModelFactory.Embedding(index: index); + + Assert.That(embedding.Index, Is.EqualTo(index)); + Assert.That(embedding.Vector.ToArray(), Is.Not.Null.And.Empty); + } + + [Test] + public void EmbeddingWithVectorWorks() + { + IEnumerable vector = [ 1f, 2f, 3f ]; + Embedding embedding = OpenAIEmbeddingsModelFactory.Embedding(vector: vector); + + Assert.That(embedding.Index, Is.EqualTo(default(int))); + Assert.That(embedding.Vector.ToArray().SequenceEqual(vector), Is.True); + } + + [Test] + public void EmbeddingCollectionWithNoPropertiesWorks() + { + EmbeddingCollection embeddingCollection = OpenAIEmbeddingsModelFactory.EmbeddingCollection(); + + Assert.That(embeddingCollection.Count, Is.EqualTo(0)); + Assert.That(embeddingCollection.Model, Is.Null); + Assert.That(embeddingCollection.Usage, Is.Null); + } + + [Test] + public void EmbeddingCollectionWithItemsWorks() + { + IEnumerable items = [ + OpenAIEmbeddingsModelFactory.Embedding(index: 10), + OpenAIEmbeddingsModelFactory.Embedding(index: 20) + ]; + EmbeddingCollection embeddingCollection = OpenAIEmbeddingsModelFactory.EmbeddingCollection(items: items); + + Assert.That(embeddingCollection.SequenceEqual(items), Is.True); + Assert.That(embeddingCollection.Model, Is.Null); + Assert.That(embeddingCollection.Usage, Is.Null); + } + + [Test] + public void EmbeddingCollectionWithModelWorks() + { + string model = "supermodel"; + EmbeddingCollection embeddingCollection = OpenAIEmbeddingsModelFactory.EmbeddingCollection(model: model); + + Assert.That(embeddingCollection.Count, Is.EqualTo(0)); + Assert.That(embeddingCollection.Model, Is.EqualTo(model)); + Assert.That(embeddingCollection.Usage, Is.Null); + } + + [Test] + public void EmbeddingCollectionWithUsageWorks() + { + EmbeddingTokenUsage usage = OpenAIEmbeddingsModelFactory.EmbeddingTokenUsage(inputTokens: 10); + EmbeddingCollection embeddingCollection = OpenAIEmbeddingsModelFactory.EmbeddingCollection(usage: usage); + + Assert.That(embeddingCollection.Count, Is.EqualTo(0)); + Assert.That(embeddingCollection.Model, Is.Null); + Assert.That(embeddingCollection.Usage, Is.EqualTo(usage)); + } + + [Test] + public void EmbeddingTokenUsageWithNoPropertiesWorks() + { + EmbeddingTokenUsage embeddingTokenUsage = OpenAIEmbeddingsModelFactory.EmbeddingTokenUsage(); + + Assert.That(embeddingTokenUsage.InputTokens, Is.EqualTo(default(int))); + Assert.That(embeddingTokenUsage.TotalTokens, Is.EqualTo(default(int))); + } + + [Test] + public void EmbeddingTokenUsageWithInputTokensWorks() + { + int inputTokens = 10; + EmbeddingTokenUsage embeddingTokenUsage = OpenAIEmbeddingsModelFactory.EmbeddingTokenUsage(inputTokens: inputTokens); + + Assert.That(embeddingTokenUsage.InputTokens, Is.EqualTo(10)); + Assert.That(embeddingTokenUsage.TotalTokens, Is.EqualTo(default(int))); + } + + [Test] + public void EmbeddingTokenUsageWithTotalTokensWorks() + { + int totalTokens = 10; + EmbeddingTokenUsage embeddingTokenUsage = OpenAIEmbeddingsModelFactory.EmbeddingTokenUsage(totalTokens: totalTokens); + + Assert.That(embeddingTokenUsage.InputTokens, Is.EqualTo(default(int))); + Assert.That(embeddingTokenUsage.TotalTokens, Is.EqualTo(totalTokens)); + } + } +} diff --git a/tests/Images/OpenAIImagesModelFactoryTests.cs b/tests/Images/OpenAIImagesModelFactoryTests.cs new file mode 100644 index 00000000..11d70277 --- /dev/null +++ b/tests/Images/OpenAIImagesModelFactoryTests.cs @@ -0,0 +1,87 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using NUnit.Framework; +using OpenAI.Images; + +namespace OpenAI.Tests.Images; + +[Parallelizable(ParallelScope.All)] +[Category("Smoke")] +public partial class OpenAIImagesModelFactoryTests +{ + [Test] + public void GeneratedImageWithNoPropertiesWorks() + { + GeneratedImage generatedImage = OpenAIImagesModelFactory.GeneratedImage(); + + Assert.That(generatedImage.ImageBytes, Is.Null); + Assert.That(generatedImage.ImageUri, Is.Null); + Assert.That(generatedImage.RevisedPrompt, Is.Null); + } + + [Test] + public void GeneratedImageWithImageBytesWorks() + { + BinaryData imageBytes = BinaryData.FromString("Definitely an image."); + GeneratedImage generatedImage = OpenAIImagesModelFactory.GeneratedImage(imageBytes: imageBytes); + + Assert.That(generatedImage.ImageBytes, Is.EqualTo(imageBytes)); + Assert.That(generatedImage.ImageUri, Is.Null); + Assert.That(generatedImage.RevisedPrompt, Is.Null); + } + + [Test] + public void GeneratedImageWithImageUriWorks() + { + Uri imageUri = new Uri("https://definitely-a-website.com/"); + GeneratedImage generatedImage = OpenAIImagesModelFactory.GeneratedImage(imageUri: imageUri); + + Assert.That(generatedImage.ImageBytes, Is.Null); + Assert.That(generatedImage.ImageUri, Is.EqualTo(imageUri)); + Assert.That(generatedImage.RevisedPrompt, Is.Null); + } + + [Test] + public void GeneratedImageWithRevisedPromptWorks() + { + string revisedPrompt = "I've been revised."; + GeneratedImage generatedImage = OpenAIImagesModelFactory.GeneratedImage(revisedPrompt: revisedPrompt); + + Assert.That(generatedImage.ImageBytes, Is.Null); + Assert.That(generatedImage.ImageUri, Is.Null); + Assert.That(generatedImage.RevisedPrompt, Is.EqualTo(revisedPrompt)); + } + + [Test] + public void GeneratedImageCollectionWithNoPropertiesWorks() + { + GeneratedImageCollection generatedImageCollection = OpenAIImagesModelFactory.GeneratedImageCollection(); + + Assert.That(generatedImageCollection.CreatedAt, Is.EqualTo(default(DateTimeOffset))); + Assert.That(generatedImageCollection.Count, Is.EqualTo(0)); + } + + [Test] + public void GeneratedImageCollectionWithCreatedAtWorks() + { + DateTimeOffset createdAt = DateTimeOffset.UtcNow; + GeneratedImageCollection generatedImageCollection = OpenAIImagesModelFactory.GeneratedImageCollection(createdAt: createdAt); + + Assert.That(generatedImageCollection.CreatedAt, Is.EqualTo(createdAt)); + Assert.That(generatedImageCollection.Count, Is.EqualTo(0)); + } + + [Test] + public void GeneratedImageCollectionWithItemsWorks() + { + IEnumerable items = [ + OpenAIImagesModelFactory.GeneratedImage(revisedPrompt: "This is the first prompt."), + OpenAIImagesModelFactory.GeneratedImage(revisedPrompt: "This is not the first prompt.") + ]; + GeneratedImageCollection generatedImageCollection = OpenAIImagesModelFactory.GeneratedImageCollection(items: items); + + Assert.That(generatedImageCollection.CreatedAt, Is.EqualTo(default(DateTimeOffset))); + Assert.That(generatedImageCollection.SequenceEqual(items), Is.True); + } +}