diff --git a/models/spring-ai-anthropic/src/test/java/org/springframework/ai/anthropic/AnthropicChatOptionsTests.java b/models/spring-ai-anthropic/src/test/java/org/springframework/ai/anthropic/AnthropicChatOptionsTests.java index d9470070e95..e733185de44 100644 --- a/models/spring-ai-anthropic/src/test/java/org/springframework/ai/anthropic/AnthropicChatOptionsTests.java +++ b/models/spring-ai-anthropic/src/test/java/org/springframework/ai/anthropic/AnthropicChatOptionsTests.java @@ -20,6 +20,7 @@ import java.util.List; import java.util.Map; +import nl.jqno.equalsverifier.EqualsVerifier; import org.junit.jupiter.api.Test; import org.springframework.ai.anthropic.api.AnthropicApi.ChatCompletionRequest.Metadata; @@ -159,6 +160,8 @@ void testCopyMutationDoesNotAffectOriginal() { assertThat(copy.getModel()).isEqualTo("modified-model"); assertThat(copy.getMaxTokens()).isEqualTo(200); assertThat(copy.getTemperature()).isEqualTo(0.8); + + EqualsVerifier.simple().forClass(AnthropicChatOptions.class).usingGetClass().verify(); } @Test diff --git a/models/spring-ai-azure-openai/src/main/java/org/springframework/ai/azure/openai/AzureOpenAiAudioTranscriptionOptions.java b/models/spring-ai-azure-openai/src/main/java/org/springframework/ai/azure/openai/AzureOpenAiAudioTranscriptionOptions.java index e6ce7592bf8..99da948ed1b 100644 --- a/models/spring-ai-azure-openai/src/main/java/org/springframework/ai/azure/openai/AzureOpenAiAudioTranscriptionOptions.java +++ b/models/spring-ai-azure-openai/src/main/java/org/springframework/ai/azure/openai/AzureOpenAiAudioTranscriptionOptions.java @@ -17,6 +17,7 @@ package org.springframework.ai.azure.openai; import java.util.List; +import java.util.Objects; import com.azure.ai.openai.models.AudioTranscriptionFormat; import com.azure.ai.openai.models.AudioTranscriptionTimestampGranularity; @@ -66,6 +67,7 @@ public class AzureOpenAiAudioTranscriptionOptions implements AudioTranscriptionO private @JsonProperty("temperature") Float temperature = 0F; private @JsonProperty("timestamp_granularities") List granularityType; + // @formatter:on public static Builder builder() { return new Builder(); @@ -129,58 +131,26 @@ public void setGranularityType(List granularityType) { } @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((this.model == null) ? 0 : this.model.hashCode()); - result = prime * result + ((this.prompt == null) ? 0 : this.prompt.hashCode()); - result = prime * result + ((this.language == null) ? 0 : this.language.hashCode()); - result = prime * result + ((this.responseFormat == null) ? 0 : this.responseFormat.hashCode()); - return result; + public final boolean equals(Object o) { + if (!(o instanceof AzureOpenAiAudioTranscriptionOptions that)) + return false; + + return Objects.equals(model, that.model) && Objects.equals(deploymentName, that.deploymentName) + && responseFormat == that.responseFormat && Objects.equals(prompt, that.prompt) + && Objects.equals(language, that.language) && Objects.equals(temperature, that.temperature) + && Objects.equals(granularityType, that.granularityType); } @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj == null) { - return false; - } - if (getClass() != obj.getClass()) { - return false; - } - AzureOpenAiAudioTranscriptionOptions other = (AzureOpenAiAudioTranscriptionOptions) obj; - if (this.model == null) { - if (other.model != null) { - return false; - } - } - else if (!this.model.equals(other.model)) { - return false; - } - if (this.prompt == null) { - if (other.prompt != null) { - return false; - } - } - else if (!this.prompt.equals(other.prompt)) { - return false; - } - if (this.language == null) { - if (other.language != null) { - return false; - } - } - else if (!this.language.equals(other.language)) { - return false; - } - if (this.responseFormat == null) { - return other.responseFormat == null; - } - else { - return this.responseFormat.equals(other.responseFormat); - } + public int hashCode() { + int result = Objects.hashCode(model); + result = 31 * result + Objects.hashCode(deploymentName); + result = 31 * result + Objects.hashCode(responseFormat); + result = 31 * result + Objects.hashCode(prompt); + result = 31 * result + Objects.hashCode(language); + result = 31 * result + Objects.hashCode(temperature); + result = 31 * result + Objects.hashCode(granularityType); + return result; } public enum WhisperModel { diff --git a/models/spring-ai-azure-openai/src/main/java/org/springframework/ai/azure/openai/AzureOpenAiChatOptions.java b/models/spring-ai-azure-openai/src/main/java/org/springframework/ai/azure/openai/AzureOpenAiChatOptions.java index da442b4ad4d..852df260e23 100644 --- a/models/spring-ai-azure-openai/src/main/java/org/springframework/ai/azure/openai/AzureOpenAiChatOptions.java +++ b/models/spring-ai-azure-openai/src/main/java/org/springframework/ai/azure/openai/AzureOpenAiChatOptions.java @@ -504,7 +504,8 @@ public boolean equals(Object o) { && Objects.equals(this.toolCallbacks, that.toolCallbacks) && Objects.equals(this.toolNames, that.toolNames) && Objects.equals(this.internalToolExecutionEnabled, that.internalToolExecutionEnabled) - && Objects.equals(this.logprobs, that.logprobs) && Objects.equals(this.topLogProbs, that.topLogProbs) + && Objects.equals(this.seed, that.seed) && Objects.equals(this.logprobs, that.logprobs) + && Objects.equals(this.topLogProbs, that.topLogProbs) && Objects.equals(this.enhancements, that.enhancements) && Objects.equals(this.streamOptions, that.streamOptions) && Objects.equals(this.enableStreamUsage, that.enableStreamUsage) diff --git a/models/spring-ai-azure-openai/src/main/java/org/springframework/ai/azure/openai/AzureOpenAiEmbeddingOptions.java b/models/spring-ai-azure-openai/src/main/java/org/springframework/ai/azure/openai/AzureOpenAiEmbeddingOptions.java index 52431f13bb2..f4d9b809ef5 100644 --- a/models/spring-ai-azure-openai/src/main/java/org/springframework/ai/azure/openai/AzureOpenAiEmbeddingOptions.java +++ b/models/spring-ai-azure-openai/src/main/java/org/springframework/ai/azure/openai/AzureOpenAiEmbeddingOptions.java @@ -17,6 +17,7 @@ package org.springframework.ai.azure.openai; import java.util.List; +import java.util.Objects; import com.fasterxml.jackson.annotation.JsonIgnore; @@ -105,6 +106,24 @@ public void setDimensions(Integer dimensions) { this.dimensions = dimensions; } + @Override + public final boolean equals(Object o) { + if (!(o instanceof AzureOpenAiEmbeddingOptions that)) + return false; + + return Objects.equals(user, that.user) && Objects.equals(deploymentName, that.deploymentName) + && Objects.equals(inputType, that.inputType) && Objects.equals(dimensions, that.dimensions); + } + + @Override + public int hashCode() { + int result = Objects.hashCode(user); + result = 31 * result + Objects.hashCode(deploymentName); + result = 31 * result + Objects.hashCode(inputType); + result = 31 * result + Objects.hashCode(dimensions); + return result; + } + public com.azure.ai.openai.models.EmbeddingsOptions toAzureOptions(List instructions) { var azureOptions = new com.azure.ai.openai.models.EmbeddingsOptions(instructions); diff --git a/models/spring-ai-azure-openai/src/test/java/org/springframework/ai/azure/openai/AzureOpenAiAudioTranscriptionOptionsTests.java b/models/spring-ai-azure-openai/src/test/java/org/springframework/ai/azure/openai/AzureOpenAiAudioTranscriptionOptionsTests.java new file mode 100644 index 00000000000..3bfd3191979 --- /dev/null +++ b/models/spring-ai-azure-openai/src/test/java/org/springframework/ai/azure/openai/AzureOpenAiAudioTranscriptionOptionsTests.java @@ -0,0 +1,29 @@ +/* + * Copyright 2025-2025 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.ai.azure.openai; + +import nl.jqno.equalsverifier.EqualsVerifier; +import org.junit.jupiter.api.Test; + +class AzureOpenAiAudioTranscriptionOptionsTests { + + @Test + void testEqualsAndHashCode() { + EqualsVerifier.simple().forClass(AzureOpenAiAudioTranscriptionOptions.class).usingGetClass().verify(); + } + +} diff --git a/models/spring-ai-azure-openai/src/test/java/org/springframework/ai/azure/openai/AzureOpenAiChatOptionsTests.java b/models/spring-ai-azure-openai/src/test/java/org/springframework/ai/azure/openai/AzureOpenAiChatOptionsTests.java index 789635d358e..7f266a611bd 100644 --- a/models/spring-ai-azure-openai/src/test/java/org/springframework/ai/azure/openai/AzureOpenAiChatOptionsTests.java +++ b/models/spring-ai-azure-openai/src/test/java/org/springframework/ai/azure/openai/AzureOpenAiChatOptionsTests.java @@ -23,6 +23,7 @@ import com.azure.ai.openai.models.AzureChatGroundingEnhancementConfiguration; import com.azure.ai.openai.models.AzureChatOCREnhancementConfiguration; import com.azure.ai.openai.models.ChatCompletionStreamOptions; +import nl.jqno.equalsverifier.EqualsVerifier; import org.junit.jupiter.api.Test; import static org.assertj.core.api.Assertions.assertThat; @@ -34,6 +35,11 @@ */ class AzureOpenAiChatOptionsTests { + @Test + void testEqualsAndHashCode() { + EqualsVerifier.simple().forClass(AzureOpenAiChatOptions.class).usingGetClass().verify(); + } + @Test void testBuilderWithAllFields() { AzureOpenAiResponseFormat responseFormat = AzureOpenAiResponseFormat.builder() diff --git a/models/spring-ai-azure-openai/src/test/java/org/springframework/ai/azure/openai/AzureOpenAiEmbeddingOptionsTests.java b/models/spring-ai-azure-openai/src/test/java/org/springframework/ai/azure/openai/AzureOpenAiEmbeddingOptionsTests.java new file mode 100644 index 00000000000..df3aeec7b48 --- /dev/null +++ b/models/spring-ai-azure-openai/src/test/java/org/springframework/ai/azure/openai/AzureOpenAiEmbeddingOptionsTests.java @@ -0,0 +1,29 @@ +/* + * Copyright 2025-2025 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.ai.azure.openai; + +import nl.jqno.equalsverifier.EqualsVerifier; +import org.junit.jupiter.api.Test; + +class AzureOpenAiEmbeddingOptionsTests { + + @Test + void testEqualsAndHashCode() { + EqualsVerifier.simple().forClass(AzureOpenAiEmbeddingOptions.class).usingGetClass().verify(); + } + +} diff --git a/models/spring-ai-azure-openai/src/test/java/org/springframework/ai/azure/openai/AzureOpenAiImageOptionsTests.java b/models/spring-ai-azure-openai/src/test/java/org/springframework/ai/azure/openai/AzureOpenAiImageOptionsTests.java new file mode 100644 index 00000000000..4ef08a41db8 --- /dev/null +++ b/models/spring-ai-azure-openai/src/test/java/org/springframework/ai/azure/openai/AzureOpenAiImageOptionsTests.java @@ -0,0 +1,29 @@ +/* + * Copyright 2025-2025 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.ai.azure.openai; + +import nl.jqno.equalsverifier.EqualsVerifier; +import org.junit.jupiter.api.Test; + +class AzureOpenAiImageOptionsTests { + + @Test + void testEqualsAndHashCode() { + EqualsVerifier.simple().forClass(AzureOpenAiImageOptions.class).usingGetClass().verify(); + } + +} diff --git a/models/spring-ai-bedrock-converse/src/test/java/org/springframework/ai/bedrock/converse/BedrockChatOptionsTests.java b/models/spring-ai-bedrock-converse/src/test/java/org/springframework/ai/bedrock/converse/BedrockChatOptionsTests.java index aed48c1a3b5..73abc41e578 100644 --- a/models/spring-ai-bedrock-converse/src/test/java/org/springframework/ai/bedrock/converse/BedrockChatOptionsTests.java +++ b/models/spring-ai-bedrock-converse/src/test/java/org/springframework/ai/bedrock/converse/BedrockChatOptionsTests.java @@ -16,11 +16,12 @@ package org.springframework.ai.bedrock.converse; -import org.junit.jupiter.api.Test; - import java.util.List; import java.util.Map; +import nl.jqno.equalsverifier.EqualsVerifier; +import org.junit.jupiter.api.Test; + import static org.assertj.core.api.Assertions.assertThat; /** @@ -30,6 +31,11 @@ */ class BedrockChatOptionsTests { + @Test + void testEqualsAndHashCode() { + EqualsVerifier.simple().forClass(BedrockChatOptions.class).usingGetClass().verify(); + } + @Test void testBuilderWithAllFields() { BedrockChatOptions options = BedrockChatOptions.builder() diff --git a/models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/cohere/BedrockCohereEmbeddingOptions.java b/models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/cohere/BedrockCohereEmbeddingOptions.java index 2013425c335..2aa9331a5c2 100644 --- a/models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/cohere/BedrockCohereEmbeddingOptions.java +++ b/models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/cohere/BedrockCohereEmbeddingOptions.java @@ -16,6 +16,8 @@ package org.springframework.ai.bedrock.cohere; +import java.util.Objects; + import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude.Include; @@ -84,6 +86,21 @@ public Integer getDimensions() { return null; } + @Override + public final boolean equals(Object o) { + if (!(o instanceof BedrockCohereEmbeddingOptions that)) + return false; + + return inputType == that.inputType && truncate == that.truncate; + } + + @Override + public int hashCode() { + int result = Objects.hashCode(inputType); + result = 31 * result + Objects.hashCode(truncate); + return result; + } + public static class Builder { private BedrockCohereEmbeddingOptions options = new BedrockCohereEmbeddingOptions(); diff --git a/models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/titan/BedrockTitanEmbeddingOptions.java b/models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/titan/BedrockTitanEmbeddingOptions.java index 9f6237e0186..816a62574ce 100644 --- a/models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/titan/BedrockTitanEmbeddingOptions.java +++ b/models/spring-ai-bedrock/src/main/java/org/springframework/ai/bedrock/titan/BedrockTitanEmbeddingOptions.java @@ -16,6 +16,8 @@ package org.springframework.ai.bedrock.titan; +import java.util.Objects; + import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude.Include; @@ -56,6 +58,19 @@ public String getModel() { return null; } + @Override + public final boolean equals(Object o) { + if (!(o instanceof BedrockTitanEmbeddingOptions that)) + return false; + + return inputType == that.inputType; + } + + @Override + public int hashCode() { + return Objects.hashCode(inputType); + } + @Override @JsonIgnore public Integer getDimensions() { diff --git a/models/spring-ai-bedrock/src/test/java/org/springframework/ai/bedrock/cohere/BedrockCohereEmbeddingOptionsTests.java b/models/spring-ai-bedrock/src/test/java/org/springframework/ai/bedrock/cohere/BedrockCohereEmbeddingOptionsTests.java new file mode 100644 index 00000000000..452cd167776 --- /dev/null +++ b/models/spring-ai-bedrock/src/test/java/org/springframework/ai/bedrock/cohere/BedrockCohereEmbeddingOptionsTests.java @@ -0,0 +1,29 @@ +/* + * Copyright 2025-2025 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.ai.bedrock.cohere; + +import nl.jqno.equalsverifier.EqualsVerifier; +import org.junit.jupiter.api.Test; + +class BedrockCohereEmbeddingOptionsTests { + + @Test + void testEqualsAndHashCode() { + EqualsVerifier.simple().forClass(BedrockCohereEmbeddingOptions.class).usingGetClass().verify(); + } + +} diff --git a/models/spring-ai-bedrock/src/test/java/org/springframework/ai/bedrock/titan/BedrockTitanEmbeddingOptionsTests.java b/models/spring-ai-bedrock/src/test/java/org/springframework/ai/bedrock/titan/BedrockTitanEmbeddingOptionsTests.java new file mode 100644 index 00000000000..7fa8a2d62da --- /dev/null +++ b/models/spring-ai-bedrock/src/test/java/org/springframework/ai/bedrock/titan/BedrockTitanEmbeddingOptionsTests.java @@ -0,0 +1,29 @@ +/* + * Copyright 2025-2025 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.ai.bedrock.titan; + +import nl.jqno.equalsverifier.EqualsVerifier; +import org.junit.jupiter.api.Test; + +class BedrockTitanEmbeddingOptionsTests { + + @Test + void testEqualsAndHashCode() { + EqualsVerifier.simple().forClass(BedrockTitanEmbeddingOptions.class).usingGetClass().verify(); + } + +} diff --git a/models/spring-ai-deepseek/src/test/java/org/springframework/ai/deepseek/DeepSeekChatOptionsTests.java b/models/spring-ai-deepseek/src/test/java/org/springframework/ai/deepseek/DeepSeekChatOptionsTests.java new file mode 100644 index 00000000000..fa45873825c --- /dev/null +++ b/models/spring-ai-deepseek/src/test/java/org/springframework/ai/deepseek/DeepSeekChatOptionsTests.java @@ -0,0 +1,34 @@ +/* + * Copyright 2025-2025 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.ai.deepseek; + +import nl.jqno.equalsverifier.EqualsVerifier; +import org.junit.jupiter.api.Test; + +/** + * Tests for {@link DeepSeekChatOptions}. + * + * @author YunKui Lu + */ +class DeepSeekChatOptionsTests { + + @Test + void testEqualsAndHashCode() { + EqualsVerifier.simple().forClass(DeepSeekChatOptions.class).usingGetClass().verify(); + } + +} diff --git a/models/spring-ai-elevenlabs/src/main/java/org/springframework/ai/elevenlabs/ElevenLabsTextToSpeechOptions.java b/models/spring-ai-elevenlabs/src/main/java/org/springframework/ai/elevenlabs/ElevenLabsTextToSpeechOptions.java index d60584a115b..1b808d8fc87 100644 --- a/models/spring-ai-elevenlabs/src/main/java/org/springframework/ai/elevenlabs/ElevenLabsTextToSpeechOptions.java +++ b/models/spring-ai-elevenlabs/src/main/java/org/springframework/ai/elevenlabs/ElevenLabsTextToSpeechOptions.java @@ -269,8 +269,8 @@ public boolean equals(Object o) { if (!(o instanceof ElevenLabsTextToSpeechOptions that)) return false; return Objects.equals(modelId, that.modelId) && Objects.equals(voiceId, that.voiceId) - && Objects.equals(outputFormat, that.outputFormat) && Objects.equals(voiceSettings, that.voiceSettings) - && Objects.equals(languageCode, that.languageCode) + && Objects.equals(enableLogging, that.enableLogging) && Objects.equals(outputFormat, that.outputFormat) + && Objects.equals(voiceSettings, that.voiceSettings) && Objects.equals(languageCode, that.languageCode) && Objects.equals(pronunciationDictionaryLocators, that.pronunciationDictionaryLocators) && Objects.equals(seed, that.seed) && Objects.equals(previousText, that.previousText) && Objects.equals(nextText, that.nextText) @@ -282,7 +282,7 @@ public boolean equals(Object o) { @Override public int hashCode() { - return Objects.hash(modelId, voiceId, outputFormat, voiceSettings, languageCode, + return Objects.hash(modelId, voiceId, enableLogging, outputFormat, voiceSettings, languageCode, pronunciationDictionaryLocators, seed, previousText, nextText, previousRequestIds, nextRequestIds, applyTextNormalization, applyLanguageTextNormalization); } diff --git a/models/spring-ai-elevenlabs/src/test/java/org/springframework/ai/elevenlabs/ElevenLabsTextToSpeechOptionsTests.java b/models/spring-ai-elevenlabs/src/test/java/org/springframework/ai/elevenlabs/ElevenLabsTextToSpeechOptionsTests.java index 624835fb390..f27ec221a37 100644 --- a/models/spring-ai-elevenlabs/src/test/java/org/springframework/ai/elevenlabs/ElevenLabsTextToSpeechOptionsTests.java +++ b/models/spring-ai-elevenlabs/src/test/java/org/springframework/ai/elevenlabs/ElevenLabsTextToSpeechOptionsTests.java @@ -18,6 +18,7 @@ import java.util.List; +import nl.jqno.equalsverifier.EqualsVerifier; import org.junit.jupiter.api.Test; import org.springframework.ai.elevenlabs.api.ElevenLabsApi; @@ -33,7 +34,12 @@ * * @author Alexandros Pappas */ -public class ElevenLabsTextToSpeechOptionsTests { +class ElevenLabsTextToSpeechOptionsTests { + + @Test + void testEqualsAndHashCode() { + EqualsVerifier.simple().forClass(ElevenLabsTextToSpeechOptions.class).usingGetClass().verify(); + } @Test public void testBuilderWithAllFields() { diff --git a/models/spring-ai-google-genai-embedding/src/main/java/org/springframework/ai/google/genai/text/GoogleGenAiTextEmbeddingOptions.java b/models/spring-ai-google-genai-embedding/src/main/java/org/springframework/ai/google/genai/text/GoogleGenAiTextEmbeddingOptions.java index 2f21a2ecca2..d04b7f7e6ea 100644 --- a/models/spring-ai-google-genai-embedding/src/main/java/org/springframework/ai/google/genai/text/GoogleGenAiTextEmbeddingOptions.java +++ b/models/spring-ai-google-genai-embedding/src/main/java/org/springframework/ai/google/genai/text/GoogleGenAiTextEmbeddingOptions.java @@ -16,6 +16,8 @@ package org.springframework.ai.google.genai.text; +import java.util.Objects; + import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude.Include; import com.fasterxml.jackson.annotation.JsonProperty; @@ -130,6 +132,26 @@ public void setAutoTruncate(Boolean autoTruncate) { this.autoTruncate = autoTruncate; } + @Override + public final boolean equals(Object o) { + if (!(o instanceof GoogleGenAiTextEmbeddingOptions that)) + return false; + + return Objects.equals(model, that.model) && taskType == that.taskType + && Objects.equals(dimensions, that.dimensions) && Objects.equals(title, that.title) + && Objects.equals(autoTruncate, that.autoTruncate); + } + + @Override + public int hashCode() { + int result = Objects.hashCode(model); + result = 31 * result + Objects.hashCode(taskType); + result = 31 * result + Objects.hashCode(dimensions); + result = 31 * result + Objects.hashCode(title); + result = 31 * result + Objects.hashCode(autoTruncate); + return result; + } + public enum TaskType { /** diff --git a/models/spring-ai-google-genai-embedding/src/test/java/org/springframework/ai/google/genai/text/GoogleGenAiTextEmbeddingOptionsTests.java b/models/spring-ai-google-genai-embedding/src/test/java/org/springframework/ai/google/genai/text/GoogleGenAiTextEmbeddingOptionsTests.java new file mode 100644 index 00000000000..d16afe808da --- /dev/null +++ b/models/spring-ai-google-genai-embedding/src/test/java/org/springframework/ai/google/genai/text/GoogleGenAiTextEmbeddingOptionsTests.java @@ -0,0 +1,29 @@ +/* + * Copyright 2025-2025 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.ai.google.genai.text; + +import nl.jqno.equalsverifier.EqualsVerifier; +import org.junit.jupiter.api.Test; + +class GoogleGenAiTextEmbeddingOptionsTests { + + @Test + void testEqualsAndHashCode() { + EqualsVerifier.simple().forClass(GoogleGenAiTextEmbeddingOptions.class).usingGetClass().verify(); + } + +} diff --git a/models/spring-ai-google-genai/src/test/java/org/springframework/ai/google/genai/GoogleGenAiChatOptionsTests.java b/models/spring-ai-google-genai/src/test/java/org/springframework/ai/google/genai/GoogleGenAiChatOptionsTests.java new file mode 100644 index 00000000000..27b16a37cb2 --- /dev/null +++ b/models/spring-ai-google-genai/src/test/java/org/springframework/ai/google/genai/GoogleGenAiChatOptionsTests.java @@ -0,0 +1,32 @@ +/* + * Copyright 2025-2025 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.ai.google.genai; + +import nl.jqno.equalsverifier.EqualsVerifier; +import org.junit.jupiter.api.Test; + +/** + * @author YunKui Lu + */ +class GoogleGenAiChatOptionsTests { + + @Test + void testEqualsAndHashCode() { + EqualsVerifier.simple().forClass(GoogleGenAiChatOptions.class).usingGetClass().verify(); + } + +} diff --git a/models/spring-ai-minimax/src/main/java/org/springframework/ai/minimax/MiniMaxEmbeddingOptions.java b/models/spring-ai-minimax/src/main/java/org/springframework/ai/minimax/MiniMaxEmbeddingOptions.java index 2fe66ea3483..8e63094c9f9 100644 --- a/models/spring-ai-minimax/src/main/java/org/springframework/ai/minimax/MiniMaxEmbeddingOptions.java +++ b/models/spring-ai-minimax/src/main/java/org/springframework/ai/minimax/MiniMaxEmbeddingOptions.java @@ -16,6 +16,8 @@ package org.springframework.ai.minimax; +import java.util.Objects; + import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude.Include; @@ -59,6 +61,19 @@ public Integer getDimensions() { return null; } + @Override + public final boolean equals(Object o) { + if (!(o instanceof MiniMaxEmbeddingOptions that)) + return false; + + return Objects.equals(model, that.model); + } + + @Override + public int hashCode() { + return Objects.hashCode(model); + } + public static class Builder { protected MiniMaxEmbeddingOptions options; diff --git a/models/spring-ai-minimax/src/test/java/org/springframework/ai/minimax/MiniMaxChatOptionsTests.java b/models/spring-ai-minimax/src/test/java/org/springframework/ai/minimax/MiniMaxChatOptionsTests.java index cbcd25a87de..697dccc8d35 100644 --- a/models/spring-ai-minimax/src/test/java/org/springframework/ai/minimax/MiniMaxChatOptionsTests.java +++ b/models/spring-ai-minimax/src/test/java/org/springframework/ai/minimax/MiniMaxChatOptionsTests.java @@ -16,13 +16,15 @@ package org.springframework.ai.minimax; -import org.junit.jupiter.api.Test; -import org.springframework.ai.minimax.api.MiniMaxApi; - import java.util.List; import java.util.Map; import java.util.Set; +import nl.jqno.equalsverifier.EqualsVerifier; +import org.junit.jupiter.api.Test; + +import org.springframework.ai.minimax.api.MiniMaxApi; + import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.assertThatThrownBy; @@ -33,6 +35,11 @@ */ class MiniMaxChatOptionsTests { + @Test + void testEqualsAndHashCode() { + EqualsVerifier.simple().forClass(MiniMaxChatOptions.class).usingGetClass().verify(); + } + @Test void testBuilderWithAllFields() { MiniMaxChatOptions options = MiniMaxChatOptions.builder() diff --git a/models/spring-ai-minimax/src/test/java/org/springframework/ai/minimax/MiniMaxEmbeddingOptionsTests.java b/models/spring-ai-minimax/src/test/java/org/springframework/ai/minimax/MiniMaxEmbeddingOptionsTests.java new file mode 100644 index 00000000000..7d11982c6ad --- /dev/null +++ b/models/spring-ai-minimax/src/test/java/org/springframework/ai/minimax/MiniMaxEmbeddingOptionsTests.java @@ -0,0 +1,29 @@ +/* + * Copyright 2025-2025 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.ai.minimax; + +import nl.jqno.equalsverifier.EqualsVerifier; +import org.junit.jupiter.api.Test; + +class MiniMaxEmbeddingOptionsTests { + + @Test + void testEqualsAndHashCode() { + EqualsVerifier.simple().forClass(MiniMaxEmbeddingOptions.class).usingGetClass().verify(); + } + +} diff --git a/models/spring-ai-mistral-ai/src/main/java/org/springframework/ai/mistralai/MistralAiChatOptions.java b/models/spring-ai-mistral-ai/src/main/java/org/springframework/ai/mistralai/MistralAiChatOptions.java index 801c35f2118..874649a84ac 100644 --- a/models/spring-ai-mistral-ai/src/main/java/org/springframework/ai/mistralai/MistralAiChatOptions.java +++ b/models/spring-ai-mistral-ai/src/main/java/org/springframework/ai/mistralai/MistralAiChatOptions.java @@ -376,7 +376,8 @@ public MistralAiChatOptions copy() { public int hashCode() { return Objects.hash(this.model, this.temperature, this.topP, this.maxTokens, this.safePrompt, this.randomSeed, this.responseFormat, this.stop, this.frequencyPenalty, this.presencePenalty, this.n, this.tools, - this.toolChoice, this.toolCallbacks, this.tools, this.internalToolExecutionEnabled, this.toolContext); + this.toolChoice, this.toolCallbacks, this.toolNames, this.tools, this.internalToolExecutionEnabled, + this.toolContext); } @Override diff --git a/models/spring-ai-mistral-ai/src/main/java/org/springframework/ai/mistralai/MistralAiEmbeddingOptions.java b/models/spring-ai-mistral-ai/src/main/java/org/springframework/ai/mistralai/MistralAiEmbeddingOptions.java index 98412490fe0..28718af08ea 100644 --- a/models/spring-ai-mistral-ai/src/main/java/org/springframework/ai/mistralai/MistralAiEmbeddingOptions.java +++ b/models/spring-ai-mistral-ai/src/main/java/org/springframework/ai/mistralai/MistralAiEmbeddingOptions.java @@ -16,6 +16,8 @@ package org.springframework.ai.mistralai; +import java.util.Objects; + import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude.Include; @@ -70,6 +72,21 @@ public Integer getDimensions() { return null; } + @Override + public final boolean equals(Object o) { + if (!(o instanceof MistralAiEmbeddingOptions that)) + return false; + + return Objects.equals(model, that.model) && Objects.equals(encodingFormat, that.encodingFormat); + } + + @Override + public int hashCode() { + int result = Objects.hashCode(model); + result = 31 * result + Objects.hashCode(encodingFormat); + return result; + } + public static class Builder { protected MistralAiEmbeddingOptions options; diff --git a/models/spring-ai-mistral-ai/src/main/java/org/springframework/ai/mistralai/moderation/MistralAiModerationOptions.java b/models/spring-ai-mistral-ai/src/main/java/org/springframework/ai/mistralai/moderation/MistralAiModerationOptions.java index b977e12bf84..f142b2da2e7 100644 --- a/models/spring-ai-mistral-ai/src/main/java/org/springframework/ai/mistralai/moderation/MistralAiModerationOptions.java +++ b/models/spring-ai-mistral-ai/src/main/java/org/springframework/ai/mistralai/moderation/MistralAiModerationOptions.java @@ -16,6 +16,8 @@ package org.springframework.ai.mistralai.moderation; +import java.util.Objects; + import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonProperty; @@ -49,6 +51,19 @@ public void setModel(String model) { this.model = model; } + @Override + public final boolean equals(Object o) { + if (!(o instanceof MistralAiModerationOptions that)) + return false; + + return Objects.equals(model, that.model); + } + + @Override + public int hashCode() { + return Objects.hashCode(model); + } + public static final class Builder { private final MistralAiModerationOptions options; diff --git a/models/spring-ai-mistral-ai/src/test/java/org/springframework/ai/mistralai/MistralAiChatOptionsTests.java b/models/spring-ai-mistral-ai/src/test/java/org/springframework/ai/mistralai/MistralAiChatOptionsTests.java index 119ba379795..c4e91abaf23 100644 --- a/models/spring-ai-mistral-ai/src/test/java/org/springframework/ai/mistralai/MistralAiChatOptionsTests.java +++ b/models/spring-ai-mistral-ai/src/test/java/org/springframework/ai/mistralai/MistralAiChatOptionsTests.java @@ -20,12 +20,13 @@ import java.util.List; import java.util.Map; -import static org.assertj.core.api.Assertions.assertThat; - +import nl.jqno.equalsverifier.EqualsVerifier; import org.junit.jupiter.api.Test; -import org.springframework.ai.mistralai.api.MistralAiApi.ChatCompletionRequest.ResponseFormat; import org.springframework.ai.mistralai.api.MistralAiApi; +import org.springframework.ai.mistralai.api.MistralAiApi.ChatCompletionRequest.ResponseFormat; + +import static org.assertj.core.api.Assertions.assertThat; /** * Tests for {@link MistralAiChatOptions}. @@ -210,6 +211,8 @@ void testEqualsAndHashCode() { assertThat(options1).isNotEqualTo(options3); assertThat(options1.hashCode()).isNotEqualTo(options3.hashCode()); + + EqualsVerifier.simple().forClass(MistralAiChatOptions.class).usingGetClass().verify(); } @Test diff --git a/models/spring-ai-mistral-ai/src/test/java/org/springframework/ai/mistralai/MistralAiEmbeddingOptionsTests.java b/models/spring-ai-mistral-ai/src/test/java/org/springframework/ai/mistralai/MistralAiEmbeddingOptionsTests.java new file mode 100644 index 00000000000..f1512f0fc8e --- /dev/null +++ b/models/spring-ai-mistral-ai/src/test/java/org/springframework/ai/mistralai/MistralAiEmbeddingOptionsTests.java @@ -0,0 +1,29 @@ +/* + * Copyright 2025-2025 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.ai.mistralai; + +import nl.jqno.equalsverifier.EqualsVerifier; +import org.junit.jupiter.api.Test; + +class MistralAiEmbeddingOptionsTests { + + @Test + void testEqualsAndHashCode() { + EqualsVerifier.simple().forClass(MistralAiEmbeddingOptions.class).usingGetClass().verify(); + } + +} diff --git a/models/spring-ai-mistral-ai/src/test/java/org/springframework/ai/mistralai/moderation/MistralAiModerationOptionsTests.java b/models/spring-ai-mistral-ai/src/test/java/org/springframework/ai/mistralai/moderation/MistralAiModerationOptionsTests.java new file mode 100644 index 00000000000..5671eccad92 --- /dev/null +++ b/models/spring-ai-mistral-ai/src/test/java/org/springframework/ai/mistralai/moderation/MistralAiModerationOptionsTests.java @@ -0,0 +1,29 @@ +/* + * Copyright 2025-2025 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.ai.mistralai.moderation; + +import nl.jqno.equalsverifier.EqualsVerifier; +import org.junit.jupiter.api.Test; + +class MistralAiModerationOptionsTests { + + @Test + void testEqualsAndHashCode() { + EqualsVerifier.simple().forClass(MistralAiModerationOptions.class).usingGetClass().verify(); + } + +} diff --git a/models/spring-ai-oci-genai/src/main/java/org/springframework/ai/oci/OCIEmbeddingOptions.java b/models/spring-ai-oci-genai/src/main/java/org/springframework/ai/oci/OCIEmbeddingOptions.java index 73fda2500fe..e68f7ed43c6 100644 --- a/models/spring-ai-oci-genai/src/main/java/org/springframework/ai/oci/OCIEmbeddingOptions.java +++ b/models/spring-ai-oci-genai/src/main/java/org/springframework/ai/oci/OCIEmbeddingOptions.java @@ -16,6 +16,8 @@ package org.springframework.ai.oci; +import java.util.Objects; + import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonProperty; import com.oracle.bmc.generativeaiinference.model.EmbedTextDetails; @@ -84,6 +86,24 @@ public void setTruncate(EmbedTextDetails.Truncate truncate) { this.truncate = truncate; } + @Override + public final boolean equals(Object o) { + if (!(o instanceof OCIEmbeddingOptions that)) + return false; + + return Objects.equals(model, that.model) && Objects.equals(compartment, that.compartment) + && Objects.equals(servingMode, that.servingMode) && truncate == that.truncate; + } + + @Override + public int hashCode() { + int result = Objects.hashCode(model); + result = 31 * result + Objects.hashCode(compartment); + result = 31 * result + Objects.hashCode(servingMode); + result = 31 * result + Objects.hashCode(truncate); + return result; + } + public static class Builder { private final OCIEmbeddingOptions options = new OCIEmbeddingOptions(); diff --git a/models/spring-ai-oci-genai/src/test/java/org/springframework/ai/oci/OCIEmbeddingOptionsTests.java b/models/spring-ai-oci-genai/src/test/java/org/springframework/ai/oci/OCIEmbeddingOptionsTests.java new file mode 100644 index 00000000000..a6bf6baceea --- /dev/null +++ b/models/spring-ai-oci-genai/src/test/java/org/springframework/ai/oci/OCIEmbeddingOptionsTests.java @@ -0,0 +1,34 @@ +/* + * Copyright 2025-2025 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.ai.oci; + +import nl.jqno.equalsverifier.EqualsVerifier; +import org.junit.jupiter.api.Test; + +/** + * Tests for {@link OCIEmbeddingOptions}. + * + * @author YunKui Lu + */ +class OCIEmbeddingOptionsTests { + + @Test + void testEqualsAndHashCode() { + EqualsVerifier.simple().forClass(OCIEmbeddingOptions.class).usingGetClass().verify(); + } + +} diff --git a/models/spring-ai-oci-genai/src/test/java/org/springframework/ai/oci/cohere/OCICohereChatOptionsTests.java b/models/spring-ai-oci-genai/src/test/java/org/springframework/ai/oci/cohere/OCICohereChatOptionsTests.java index d714d274689..ad51b9fcccd 100644 --- a/models/spring-ai-oci-genai/src/test/java/org/springframework/ai/oci/cohere/OCICohereChatOptionsTests.java +++ b/models/spring-ai-oci-genai/src/test/java/org/springframework/ai/oci/cohere/OCICohereChatOptionsTests.java @@ -21,8 +21,9 @@ import java.util.Map; import com.oracle.bmc.generativeaiinference.model.CohereTool; -import org.junit.jupiter.api.Test; +import nl.jqno.equalsverifier.EqualsVerifier; import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; import static org.assertj.core.api.Assertions.assertThat; @@ -40,6 +41,11 @@ void setUp() { options = new OCICohereChatOptions(); } + @Test + void testEqualsAndHashCode() { + EqualsVerifier.simple().forClass(OCICohereChatOptions.class).usingGetClass().verify(); + } + @Test void testBuilderWithAllFields() { OCICohereChatOptions options = OCICohereChatOptions.builder() diff --git a/models/spring-ai-ollama/pom.xml b/models/spring-ai-ollama/pom.xml index 673064e4bb1..82d610ceb8d 100644 --- a/models/spring-ai-ollama/pom.xml +++ b/models/spring-ai-ollama/pom.xml @@ -85,6 +85,13 @@ test + + org.springframework.ai + spring-ai-test + ${project.parent.version} + test + + org.springframework.boot spring-boot-starter-test diff --git a/models/spring-ai-ollama/src/test/java/org/springframework/ai/ollama/api/OllamaOptionsTests.java b/models/spring-ai-ollama/src/test/java/org/springframework/ai/ollama/api/OllamaOptionsTests.java new file mode 100644 index 00000000000..fefa3ffeb54 --- /dev/null +++ b/models/spring-ai-ollama/src/test/java/org/springframework/ai/ollama/api/OllamaOptionsTests.java @@ -0,0 +1,29 @@ +/* + * Copyright 2025-2025 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.ai.ollama.api; + +import nl.jqno.equalsverifier.EqualsVerifier; +import org.junit.jupiter.api.Test; + +class OllamaOptionsTests { + + @Test + void testEqualsAndHashCode() { + EqualsVerifier.simple().forClass(OllamaOptions.class).usingGetClass().verify(); + } + +} diff --git a/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/OpenAiAudioTranscriptionOptions.java b/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/OpenAiAudioTranscriptionOptions.java index a03688d04b9..69fb0f00bea 100644 --- a/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/OpenAiAudioTranscriptionOptions.java +++ b/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/OpenAiAudioTranscriptionOptions.java @@ -16,6 +16,8 @@ package org.springframework.ai.openai; +import java.util.Objects; + import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude.Include; import com.fasterxml.jackson.annotation.JsonProperty; @@ -58,6 +60,7 @@ public class OpenAiAudioTranscriptionOptions implements AudioTranscriptionOption private @JsonProperty("temperature") Float temperature; private @JsonProperty("timestamp_granularities") GranularityType granularityType; + // @formatter:on public static Builder builder() { return new Builder(); @@ -113,61 +116,24 @@ public void setGranularityType(GranularityType granularityType) { } @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((this.model == null) ? 0 : this.model.hashCode()); - result = prime * result + ((this.prompt == null) ? 0 : this.prompt.hashCode()); - result = prime * result + ((this.language == null) ? 0 : this.language.hashCode()); - result = prime * result + ((this.responseFormat == null) ? 0 : this.responseFormat.hashCode()); - return result; + public final boolean equals(Object o) { + if (!(o instanceof OpenAiAudioTranscriptionOptions that)) + return false; + + return Objects.equals(model, that.model) && responseFormat == that.responseFormat + && Objects.equals(prompt, that.prompt) && Objects.equals(language, that.language) + && Objects.equals(temperature, that.temperature) && granularityType == that.granularityType; } @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj == null) { - return false; - } - if (getClass() != obj.getClass()) { - return false; - } - OpenAiAudioTranscriptionOptions other = (OpenAiAudioTranscriptionOptions) obj; - if (this.model == null) { - if (other.model != null) { - return false; - } - } - else if (!this.model.equals(other.model)) { - return false; - } - if (this.prompt == null) { - if (other.prompt != null) { - return false; - } - } - else if (!this.prompt.equals(other.prompt)) { - return false; - } - if (this.language == null) { - if (other.language != null) { - return false; - } - } - else if (!this.language.equals(other.language)) { - return false; - } - if (this.responseFormat == null) { - if (other.responseFormat != null) { - return false; - } - } - else if (!this.responseFormat.equals(other.responseFormat)) { - return false; - } - return true; + public int hashCode() { + int result = Objects.hashCode(model); + result = 31 * result + Objects.hashCode(responseFormat); + result = 31 * result + Objects.hashCode(prompt); + result = 31 * result + Objects.hashCode(language); + result = 31 * result + Objects.hashCode(temperature); + result = 31 * result + Objects.hashCode(granularityType); + return result; } public static class Builder { @@ -217,4 +183,5 @@ public OpenAiAudioTranscriptionOptions build() { } } + } diff --git a/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/OpenAiEmbeddingOptions.java b/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/OpenAiEmbeddingOptions.java index 54ba275dd61..cd86c2ee34c 100644 --- a/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/OpenAiEmbeddingOptions.java +++ b/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/OpenAiEmbeddingOptions.java @@ -16,6 +16,8 @@ package org.springframework.ai.openai; +import java.util.Objects; + import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude.Include; import com.fasterxml.jackson.annotation.JsonProperty; @@ -89,6 +91,24 @@ public void setUser(String user) { this.user = user; } + @Override + public final boolean equals(Object o) { + if (!(o instanceof OpenAiEmbeddingOptions that)) + return false; + + return Objects.equals(model, that.model) && Objects.equals(encodingFormat, that.encodingFormat) + && Objects.equals(dimensions, that.dimensions) && Objects.equals(user, that.user); + } + + @Override + public int hashCode() { + int result = Objects.hashCode(model); + result = 31 * result + Objects.hashCode(encodingFormat); + result = 31 * result + Objects.hashCode(dimensions); + result = 31 * result + Objects.hashCode(user); + return result; + } + public static class Builder { protected OpenAiEmbeddingOptions options; diff --git a/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/OpenAiModerationOptions.java b/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/OpenAiModerationOptions.java index 10fdb265128..89cb1177db6 100644 --- a/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/OpenAiModerationOptions.java +++ b/models/spring-ai-openai/src/main/java/org/springframework/ai/openai/OpenAiModerationOptions.java @@ -16,6 +16,8 @@ package org.springframework.ai.openai; +import java.util.Objects; + import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonProperty; @@ -51,6 +53,19 @@ public void setModel(String model) { this.model = model; } + @Override + public final boolean equals(Object o) { + if (!(o instanceof OpenAiModerationOptions that)) + return false; + + return Objects.equals(model, that.model); + } + + @Override + public int hashCode() { + return Objects.hashCode(model); + } + public static final class Builder { private final OpenAiModerationOptions options; diff --git a/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/OpenAiAudioSpeechOptionsTests.java b/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/OpenAiAudioSpeechOptionsTests.java new file mode 100644 index 00000000000..eb4badf3123 --- /dev/null +++ b/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/OpenAiAudioSpeechOptionsTests.java @@ -0,0 +1,29 @@ +/* + * Copyright 2025-2025 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.ai.openai; + +import nl.jqno.equalsverifier.EqualsVerifier; +import org.junit.jupiter.api.Test; + +class OpenAiAudioSpeechOptionsTests { + + @Test + void testEqualsAndHashCode() { + EqualsVerifier.simple().forClass(OpenAiAudioSpeechOptions.class).usingGetClass().verify(); + } + +} diff --git a/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/OpenAiAudioTranscriptionOptionsTests.java b/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/OpenAiAudioTranscriptionOptionsTests.java new file mode 100644 index 00000000000..9e82c5c0e81 --- /dev/null +++ b/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/OpenAiAudioTranscriptionOptionsTests.java @@ -0,0 +1,29 @@ +/* + * Copyright 2025-2025 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.ai.openai; + +import nl.jqno.equalsverifier.EqualsVerifier; +import org.junit.jupiter.api.Test; + +class OpenAiAudioTranscriptionOptionsTests { + + @Test + void testEqualsAndHashCode() { + EqualsVerifier.simple().forClass(OpenAiAudioTranscriptionOptions.class).usingGetClass().verify(); + } + +} diff --git a/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/OpenAiChatOptionsTests.java b/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/OpenAiChatOptionsTests.java index 5b4dbb2f500..15cfb118a64 100644 --- a/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/OpenAiChatOptionsTests.java +++ b/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/OpenAiChatOptionsTests.java @@ -21,6 +21,7 @@ import java.util.List; import java.util.Map; +import nl.jqno.equalsverifier.EqualsVerifier; import org.junit.jupiter.api.Test; import org.springframework.ai.openai.api.OpenAiApi; @@ -309,6 +310,8 @@ void testEqualsAndHashCode() { // Test hashCode assertThat(options1.hashCode()).isEqualTo(options2.hashCode()); assertThat(options1.hashCode()).isNotEqualTo(options3.hashCode()); + + EqualsVerifier.simple().forClass(OpenAiChatOptions.class).usingGetClass().verify(); } @Test diff --git a/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/OpenAiEmbeddingOptionsTests.java b/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/OpenAiEmbeddingOptionsTests.java new file mode 100644 index 00000000000..03bc09a6c2b --- /dev/null +++ b/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/OpenAiEmbeddingOptionsTests.java @@ -0,0 +1,29 @@ +/* + * Copyright 2025-2025 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.ai.openai; + +import nl.jqno.equalsverifier.EqualsVerifier; +import org.junit.jupiter.api.Test; + +class OpenAiEmbeddingOptionsTests { + + @Test + void testEqualsAndHashCode() { + EqualsVerifier.simple().forClass(OpenAiEmbeddingOptions.class).usingGetClass().verify(); + } + +} diff --git a/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/OpenAiImageOptionsTests.java b/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/OpenAiImageOptionsTests.java index faa266ebbeb..9908443d0fe 100644 --- a/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/OpenAiImageOptionsTests.java +++ b/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/OpenAiImageOptionsTests.java @@ -16,6 +16,7 @@ package org.springframework.ai.openai; +import nl.jqno.equalsverifier.EqualsVerifier; import org.junit.jupiter.api.Test; import static org.assertj.core.api.Assertions.assertThat; @@ -193,6 +194,8 @@ void testEqualsAndHashCode() { // have // different // hash codes + + EqualsVerifier.simple().forClass(OpenAiImageOptions.class).usingGetClass().verify(); } @Test diff --git a/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/OpenAiModerationOptionsTests.java b/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/OpenAiModerationOptionsTests.java new file mode 100644 index 00000000000..eaeb7681ed5 --- /dev/null +++ b/models/spring-ai-openai/src/test/java/org/springframework/ai/openai/OpenAiModerationOptionsTests.java @@ -0,0 +1,29 @@ +/* + * Copyright 2025-2025 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.ai.openai; + +import nl.jqno.equalsverifier.EqualsVerifier; +import org.junit.jupiter.api.Test; + +class OpenAiModerationOptionsTests { + + @Test + void testEqualsAndHashCode() { + EqualsVerifier.simple().forClass(OpenAiModerationOptions.class).usingGetClass().verify(); + } + +} diff --git a/models/spring-ai-postgresml/pom.xml b/models/spring-ai-postgresml/pom.xml index caff7c1e3d1..fa1275d7fa9 100644 --- a/models/spring-ai-postgresml/pom.xml +++ b/models/spring-ai-postgresml/pom.xml @@ -64,6 +64,13 @@ test + + org.springframework.ai + spring-ai-test + ${project.parent.version} + test + + org.springframework.boot spring-boot-testcontainers diff --git a/models/spring-ai-postgresml/src/main/java/org/springframework/ai/postgresml/PostgresMlEmbeddingOptions.java b/models/spring-ai-postgresml/src/main/java/org/springframework/ai/postgresml/PostgresMlEmbeddingOptions.java index 847fdcf7e00..d9a1d50bfe1 100644 --- a/models/spring-ai-postgresml/src/main/java/org/springframework/ai/postgresml/PostgresMlEmbeddingOptions.java +++ b/models/spring-ai-postgresml/src/main/java/org/springframework/ai/postgresml/PostgresMlEmbeddingOptions.java @@ -17,6 +17,7 @@ package org.springframework.ai.postgresml; import java.util.Map; +import java.util.Objects; import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.annotation.JsonInclude; @@ -109,6 +110,24 @@ public Integer getDimensions() { return null; } + @Override + public final boolean equals(Object o) { + if (!(o instanceof PostgresMlEmbeddingOptions that)) + return false; + + return Objects.equals(transformer, that.transformer) && vectorType == that.vectorType + && Objects.equals(kwargs, that.kwargs) && metadataMode == that.metadataMode; + } + + @Override + public int hashCode() { + int result = Objects.hashCode(transformer); + result = 31 * result + Objects.hashCode(vectorType); + result = 31 * result + Objects.hashCode(kwargs); + result = 31 * result + Objects.hashCode(metadataMode); + return result; + } + public static class Builder { protected PostgresMlEmbeddingOptions options; diff --git a/models/spring-ai-postgresml/src/test/java/org/springframework/ai/postgresml/PostgresMlEmbeddingOptionsTests.java b/models/spring-ai-postgresml/src/test/java/org/springframework/ai/postgresml/PostgresMlEmbeddingOptionsTests.java index bc5cc218c11..7532ecefec6 100644 --- a/models/spring-ai-postgresml/src/test/java/org/springframework/ai/postgresml/PostgresMlEmbeddingOptionsTests.java +++ b/models/spring-ai-postgresml/src/test/java/org/springframework/ai/postgresml/PostgresMlEmbeddingOptionsTests.java @@ -18,6 +18,7 @@ import java.util.Map; +import nl.jqno.equalsverifier.EqualsVerifier; import org.junit.jupiter.api.Test; import org.mockito.Mockito; @@ -29,7 +30,12 @@ /** * @author Christian Tzolov */ -public class PostgresMlEmbeddingOptionsTests { +class PostgresMlEmbeddingOptionsTests { + + @Test + void testEqualsAndHashCode() { + EqualsVerifier.simple().forClass(PostgresMlEmbeddingOptions.class).usingGetClass().verify(); + } @Test public void defaultOptions() { diff --git a/models/spring-ai-stability-ai/src/test/java/org/springframework/ai/stabilityai/StabilityAiImageOptionsTests.java b/models/spring-ai-stability-ai/src/test/java/org/springframework/ai/stabilityai/StabilityAiImageOptionsTests.java index 854f022f2f9..96c49eeac7c 100644 --- a/models/spring-ai-stability-ai/src/test/java/org/springframework/ai/stabilityai/StabilityAiImageOptionsTests.java +++ b/models/spring-ai-stability-ai/src/test/java/org/springframework/ai/stabilityai/StabilityAiImageOptionsTests.java @@ -16,6 +16,7 @@ package org.springframework.ai.stabilityai; +import nl.jqno.equalsverifier.EqualsVerifier; import org.junit.jupiter.api.Test; import org.springframework.ai.image.ImageOptions; @@ -25,7 +26,12 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.mock; -public class StabilityAiImageOptionsTests { +class StabilityAiImageOptionsTests { + + @Test + void testEqualsAndHashCode() { + EqualsVerifier.simple().forClass(StabilityAiImageOptions.class).usingGetClass().verify(); + } @Test void shouldPreferRuntimeOptionsOverDefaultOptions() { diff --git a/models/spring-ai-vertex-ai-embedding/src/main/java/org/springframework/ai/vertexai/embedding/text/VertexAiTextEmbeddingOptions.java b/models/spring-ai-vertex-ai-embedding/src/main/java/org/springframework/ai/vertexai/embedding/text/VertexAiTextEmbeddingOptions.java index 4f384b35b26..32ebc25e089 100644 --- a/models/spring-ai-vertex-ai-embedding/src/main/java/org/springframework/ai/vertexai/embedding/text/VertexAiTextEmbeddingOptions.java +++ b/models/spring-ai-vertex-ai-embedding/src/main/java/org/springframework/ai/vertexai/embedding/text/VertexAiTextEmbeddingOptions.java @@ -16,6 +16,8 @@ package org.springframework.ai.vertexai.embedding.text; +import java.util.Objects; + import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude.Include; import com.fasterxml.jackson.annotation.JsonProperty; @@ -129,6 +131,26 @@ public void setAutoTruncate(Boolean autoTruncate) { this.autoTruncate = autoTruncate; } + @Override + public final boolean equals(Object o) { + if (!(o instanceof VertexAiTextEmbeddingOptions that)) + return false; + + return Objects.equals(model, that.model) && taskType == that.taskType + && Objects.equals(dimensions, that.dimensions) && Objects.equals(title, that.title) + && Objects.equals(autoTruncate, that.autoTruncate); + } + + @Override + public int hashCode() { + int result = Objects.hashCode(model); + result = 31 * result + Objects.hashCode(taskType); + result = 31 * result + Objects.hashCode(dimensions); + result = 31 * result + Objects.hashCode(title); + result = 31 * result + Objects.hashCode(autoTruncate); + return result; + } + public enum TaskType { /** diff --git a/models/spring-ai-vertex-ai-embedding/src/test/java/org/springframework/ai/vertexai/embedding/text/VertexAiTextEmbeddingOptionsTests.java b/models/spring-ai-vertex-ai-embedding/src/test/java/org/springframework/ai/vertexai/embedding/text/VertexAiTextEmbeddingOptionsTests.java new file mode 100644 index 00000000000..9a31d061dd4 --- /dev/null +++ b/models/spring-ai-vertex-ai-embedding/src/test/java/org/springframework/ai/vertexai/embedding/text/VertexAiTextEmbeddingOptionsTests.java @@ -0,0 +1,29 @@ +/* + * Copyright 2025-2025 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.ai.vertexai.embedding.text; + +import nl.jqno.equalsverifier.EqualsVerifier; +import org.junit.jupiter.api.Test; + +class VertexAiTextEmbeddingOptionsTests { + + @Test + void testEqualsAndHashCode() { + EqualsVerifier.simple().forClass(VertexAiTextEmbeddingOptions.class).usingGetClass().verify(); + } + +} diff --git a/models/spring-ai-vertex-ai-gemini/src/test/java/org/springframework/ai/vertexai/gemini/VertexAiGeminiChatOptionsTests.java b/models/spring-ai-vertex-ai-gemini/src/test/java/org/springframework/ai/vertexai/gemini/VertexAiGeminiChatOptionsTests.java new file mode 100644 index 00000000000..35dfbd115cc --- /dev/null +++ b/models/spring-ai-vertex-ai-gemini/src/test/java/org/springframework/ai/vertexai/gemini/VertexAiGeminiChatOptionsTests.java @@ -0,0 +1,29 @@ +/* + * Copyright 2025-2025 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.ai.vertexai.gemini; + +import nl.jqno.equalsverifier.EqualsVerifier; +import org.junit.jupiter.api.Test; + +class VertexAiGeminiChatOptionsTests { + + @Test + void testEqualsAndHashCode() { + EqualsVerifier.simple().forClass(VertexAiGeminiChatOptions.class).usingGetClass().verify(); + } + +} diff --git a/models/spring-ai-zhipuai/src/main/java/org/springframework/ai/zhipuai/ZhiPuAiChatOptions.java b/models/spring-ai-zhipuai/src/main/java/org/springframework/ai/zhipuai/ZhiPuAiChatOptions.java index c31320defe1..56be555dca1 100644 --- a/models/spring-ai-zhipuai/src/main/java/org/springframework/ai/zhipuai/ZhiPuAiChatOptions.java +++ b/models/spring-ai-zhipuai/src/main/java/org/springframework/ai/zhipuai/ZhiPuAiChatOptions.java @@ -22,6 +22,7 @@ import java.util.HashSet; import java.util.List; import java.util.Map; +import java.util.Objects; import java.util.Set; import com.fasterxml.jackson.annotation.JsonIgnore; @@ -315,134 +316,37 @@ public void setToolContext(Map toolContext) { } @Override - public int hashCode() { - final int prime = 31; - int result = 1; - result = prime * result + ((this.model == null) ? 0 : this.model.hashCode()); - result = prime * result + ((this.maxTokens == null) ? 0 : this.maxTokens.hashCode()); - result = prime * result + ((this.stop == null) ? 0 : this.stop.hashCode()); - result = prime * result + ((this.temperature == null) ? 0 : this.temperature.hashCode()); - result = prime * result + ((this.topP == null) ? 0 : this.topP.hashCode()); - result = prime * result + ((this.tools == null) ? 0 : this.tools.hashCode()); - result = prime * result + ((this.toolChoice == null) ? 0 : this.toolChoice.hashCode()); - result = prime * result + ((this.user == null) ? 0 : this.user.hashCode()); - result = prime * result - + ((this.internalToolExecutionEnabled == null) ? 0 : this.internalToolExecutionEnabled.hashCode()); - result = prime * result + ((this.toolCallbacks == null) ? 0 : this.toolCallbacks.hashCode()); - result = prime * result + ((this.toolNames == null) ? 0 : this.toolNames.hashCode()); - result = prime * result + ((this.toolContext == null) ? 0 : this.toolContext.hashCode()); - return result; + public final boolean equals(Object o) { + if (!(o instanceof ZhiPuAiChatOptions that)) + return false; + + return Objects.equals(model, that.model) && Objects.equals(maxTokens, that.maxTokens) + && Objects.equals(stop, that.stop) && Objects.equals(temperature, that.temperature) + && Objects.equals(topP, that.topP) && Objects.equals(tools, that.tools) + && Objects.equals(toolChoice, that.toolChoice) && Objects.equals(user, that.user) + && Objects.equals(requestId, that.requestId) && Objects.equals(doSample, that.doSample) + && Objects.equals(toolCallbacks, that.toolCallbacks) && Objects.equals(toolNames, that.toolNames) + && Objects.equals(internalToolExecutionEnabled, that.internalToolExecutionEnabled) + && Objects.equals(toolContext, that.toolContext); } @Override - public boolean equals(Object obj) { - if (this == obj) { - return true; - } - if (obj == null) { - return false; - } - if (getClass() != obj.getClass()) { - return false; - } - ZhiPuAiChatOptions other = (ZhiPuAiChatOptions) obj; - if (this.model == null) { - if (other.model != null) { - return false; - } - } - else if (!this.model.equals(other.model)) { - return false; - } - if (this.maxTokens == null) { - if (other.maxTokens != null) { - return false; - } - } - else if (!this.maxTokens.equals(other.maxTokens)) { - return false; - } - if (this.stop == null) { - if (other.stop != null) { - return false; - } - } - else if (!this.stop.equals(other.stop)) { - return false; - } - if (this.temperature == null) { - if (other.temperature != null) { - return false; - } - } - else if (!this.temperature.equals(other.temperature)) { - return false; - } - if (this.topP == null) { - if (other.topP != null) { - return false; - } - } - else if (!this.topP.equals(other.topP)) { - return false; - } - if (this.tools == null) { - if (other.tools != null) { - return false; - } - } - else if (!this.tools.equals(other.tools)) { - return false; - } - if (this.toolChoice == null) { - if (other.toolChoice != null) { - return false; - } - } - else if (!this.toolChoice.equals(other.toolChoice)) { - return false; - } - if (this.user == null) { - if (other.user != null) { - return false; - } - } - else if (!this.user.equals(other.user)) { - return false; - } - if (this.requestId == null) { - if (other.requestId != null) { - return false; - } - } - else if (!this.requestId.equals(other.requestId)) { - return false; - } - if (this.doSample == null) { - if (other.doSample != null) { - return false; - } - } - else if (!this.doSample.equals(other.doSample)) { - return false; - } - if (this.internalToolExecutionEnabled == null) { - if (other.internalToolExecutionEnabled != null) { - return false; - } - } - else if (!this.internalToolExecutionEnabled.equals(other.internalToolExecutionEnabled)) { - return false; - } - if (this.toolContext == null) { - if (other.toolContext != null) { - return false; - } - } - else if (!this.toolContext.equals(other.toolContext)) { - return false; - } - return true; + public int hashCode() { + int result = Objects.hashCode(model); + result = 31 * result + Objects.hashCode(maxTokens); + result = 31 * result + Objects.hashCode(stop); + result = 31 * result + Objects.hashCode(temperature); + result = 31 * result + Objects.hashCode(topP); + result = 31 * result + Objects.hashCode(tools); + result = 31 * result + Objects.hashCode(toolChoice); + result = 31 * result + Objects.hashCode(user); + result = 31 * result + Objects.hashCode(requestId); + result = 31 * result + Objects.hashCode(doSample); + result = 31 * result + Objects.hashCode(toolCallbacks); + result = 31 * result + Objects.hashCode(toolNames); + result = 31 * result + Objects.hashCode(internalToolExecutionEnabled); + result = 31 * result + Objects.hashCode(toolContext); + return result; } @Override diff --git a/models/spring-ai-zhipuai/src/main/java/org/springframework/ai/zhipuai/ZhiPuAiEmbeddingOptions.java b/models/spring-ai-zhipuai/src/main/java/org/springframework/ai/zhipuai/ZhiPuAiEmbeddingOptions.java index fc2c10161e4..65309994c26 100644 --- a/models/spring-ai-zhipuai/src/main/java/org/springframework/ai/zhipuai/ZhiPuAiEmbeddingOptions.java +++ b/models/spring-ai-zhipuai/src/main/java/org/springframework/ai/zhipuai/ZhiPuAiEmbeddingOptions.java @@ -16,6 +16,8 @@ package org.springframework.ai.zhipuai; +import java.util.Objects; + import com.fasterxml.jackson.annotation.JsonInclude; import com.fasterxml.jackson.annotation.JsonInclude.Include; import com.fasterxml.jackson.annotation.JsonProperty; @@ -66,6 +68,21 @@ public Integer getDimensions() { return this.dimensions; } + @Override + public final boolean equals(Object o) { + if (!(o instanceof ZhiPuAiEmbeddingOptions that)) + return false; + + return Objects.equals(model, that.model) && Objects.equals(dimensions, that.dimensions); + } + + @Override + public int hashCode() { + int result = Objects.hashCode(model); + result = 31 * result + Objects.hashCode(dimensions); + return result; + } + public static class Builder { protected ZhiPuAiEmbeddingOptions options; diff --git a/models/spring-ai-zhipuai/src/test/java/org/springframework/ai/zhipuai/ZhiPuAiChatOptionsTests.java b/models/spring-ai-zhipuai/src/test/java/org/springframework/ai/zhipuai/ZhiPuAiChatOptionsTests.java new file mode 100644 index 00000000000..d7befd35440 --- /dev/null +++ b/models/spring-ai-zhipuai/src/test/java/org/springframework/ai/zhipuai/ZhiPuAiChatOptionsTests.java @@ -0,0 +1,29 @@ +/* + * Copyright 2025-2025 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.ai.zhipuai; + +import nl.jqno.equalsverifier.EqualsVerifier; +import org.junit.jupiter.api.Test; + +class ZhiPuAiChatOptionsTests { + + @Test + void testEqualsAndHashCode() { + EqualsVerifier.simple().forClass(ZhiPuAiChatOptions.class).usingGetClass().verify(); + } + +} diff --git a/models/spring-ai-zhipuai/src/test/java/org/springframework/ai/zhipuai/ZhiPuAiEmbeddingOptionsTests.java b/models/spring-ai-zhipuai/src/test/java/org/springframework/ai/zhipuai/ZhiPuAiEmbeddingOptionsTests.java new file mode 100644 index 00000000000..19ea881bc50 --- /dev/null +++ b/models/spring-ai-zhipuai/src/test/java/org/springframework/ai/zhipuai/ZhiPuAiEmbeddingOptionsTests.java @@ -0,0 +1,29 @@ +/* + * Copyright 2025-2025 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.ai.zhipuai; + +import nl.jqno.equalsverifier.EqualsVerifier; +import org.junit.jupiter.api.Test; + +class ZhiPuAiEmbeddingOptionsTests { + + @Test + void testEqualsAndHashCode() { + EqualsVerifier.simple().forClass(ZhiPuAiEmbeddingOptions.class).usingGetClass().verify(); + } + +} diff --git a/models/spring-ai-zhipuai/src/test/java/org/springframework/ai/zhipuai/ZhiPuAiImageOptionsTests.java b/models/spring-ai-zhipuai/src/test/java/org/springframework/ai/zhipuai/ZhiPuAiImageOptionsTests.java new file mode 100644 index 00000000000..d6922edb96e --- /dev/null +++ b/models/spring-ai-zhipuai/src/test/java/org/springframework/ai/zhipuai/ZhiPuAiImageOptionsTests.java @@ -0,0 +1,29 @@ +/* + * Copyright 2025-2025 the original author or authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * https://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.springframework.ai.zhipuai; + +import nl.jqno.equalsverifier.EqualsVerifier; +import org.junit.jupiter.api.Test; + +class ZhiPuAiImageOptionsTests { + + @Test + void testEqualsAndHashCode() { + EqualsVerifier.simple().forClass(ZhiPuAiImageOptions.class).usingGetClass().verify(); + } + +} diff --git a/pom.xml b/pom.xml index 79483271a2a..b81b9940174 100644 --- a/pom.xml +++ b/pom.xml @@ -323,6 +323,7 @@ 4.12.0 4.1.0 + 4.0.5 0.11.0 diff --git a/spring-ai-test/pom.xml b/spring-ai-test/pom.xml index 1e405a954cb..c92c2825fd8 100644 --- a/spring-ai-test/pom.xml +++ b/spring-ai-test/pom.xml @@ -83,5 +83,11 @@ io.micrometer micrometer-observation-test + + + nl.jqno.equalsverifier + equalsverifier + ${equalsverifier.version} +