diff --git a/Gemfile.lock b/Gemfile.lock index 7068eed..748a59d 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -97,4 +97,4 @@ DEPENDENCIES simplecov (~> 0.22) BUNDLED WITH - 2.5.22 + 4.0.10 diff --git a/lib/ruby_llm/test/errors/no_response_provided_error.rb b/lib/ruby_llm/test/errors/no_response_provided_error.rb index 63c9c97..3753900 100644 --- a/lib/ruby_llm/test/errors/no_response_provided_error.rb +++ b/lib/ruby_llm/test/errors/no_response_provided_error.rb @@ -13,8 +13,7 @@ class NoResponseProvidedError < StandardError def initialize(messages) @messages = messages - - super("No test response provided for the following request:\n#{messages.last.content}") + super("No test response provided for the following request:\n#{messages.last&.content}") end end end diff --git a/test/ruby_llm/test/complete_parameters_test.rb b/test/ruby_llm/test/complete_parameters_test.rb new file mode 100644 index 0000000..3695368 --- /dev/null +++ b/test/ruby_llm/test/complete_parameters_test.rb @@ -0,0 +1,29 @@ +# frozen_string_literal: true + +require "test_helper" + +module RubyLLM + module Test + class CompleteParametersTest < Minitest::Test + def test_with_block + params_with_block = CompleteParameters.new( + messages: [], tools: [], temperature: 0.5, model: "test-model", params: {}, headers: {}, schema: nil, + thinking: nil, tool_prefs: nil, + block: -> { "test block" } + ) + + assert_predicate params_with_block, :block_received? + end + + def test_without_block + params_without_block = CompleteParameters.new( + messages: [], tools: [], temperature: 0.5, model: "test-model", params: {}, headers: {}, schema: nil, + thinking: nil, tool_prefs: nil, + block: nil + ) + + refute_predicate params_without_block, :block_received? + end + end + end +end diff --git a/test/ruby_llm/test/errors/no_response_provided_error_test.rb b/test/ruby_llm/test/errors/no_response_provided_error_test.rb new file mode 100644 index 0000000..b3558f3 --- /dev/null +++ b/test/ruby_llm/test/errors/no_response_provided_error_test.rb @@ -0,0 +1,28 @@ +# frozen_string_literal: true + +require "test_helper" + +module RubyLLM + module Test + module Errors + class NoResponseProvidedErrorTest < Minitest::Test + def test_error_message_includes_last_message_content + messages = [ + Message.new(role: :user, content: "What is the capital of France?"), + Message.new(role: :assistant, content: "The capital of France is Paris.") + ] + + error = NoResponseProvidedError.new(messages) + + assert_includes error.message, messages.last.content + end + + def test_handles_empty_messages + error = NoResponseProvidedError.new([]) + + assert_includes error.message, "No test response provided for the following request:" + end + end + end + end +end diff --git a/test/ruby_llm/test/test_provider_test.rb b/test/ruby_llm/test/test_provider_test.rb new file mode 100644 index 0000000..208ef7b --- /dev/null +++ b/test/ruby_llm/test/test_provider_test.rb @@ -0,0 +1,119 @@ +# frozen_string_literal: true + +require "test_helper" + +module RubyLLM + module Test + class TestProviderTest < Minitest::Test + def setup + RubyLLM::Test.reset + end + + def test_provider_returns_stubbed_response + RubyLLM::Test.stub_response("stubbed response") + + provider = TestProvider.new(nil, RubyLLM::Test) + response = provider.complete([], tools: [], temperature: 0.5, model: "test-model", params: {}, headers: {}) + + assert_kind_of Message, response + assert_equal "stubbed response", response.content + end + + def test_when_response_not_stubbed + provider = TestProvider.new(nil, RubyLLM::Test) + message = Message.new(role: :user, content: "What is the capital of France?") + + exception = assert_raises(Errors::NoResponseProvidedError) do + provider.complete([ message ], tools: [], temperature: 0.5, model: "test-model", params: {}, headers: {}) + end + + assert_includes exception.message, message.content + end + + def test_when_stub_is_a_message + stubbed_message = Message.new(role: :assistant, content: "This is a stubbed message.") + RubyLLM::Test.stub_response(stubbed_message) + + provider = TestProvider.new(nil, RubyLLM::Test) + response = provider.complete([], tools: [], temperature: 0.5, model: "test-model", params: {}, headers: {}) + + assert_equal stubbed_message, response + end + + def test_hash_stub_is_converted_to_json_message + stubbed_hash = { answer: "42" } + RubyLLM::Test.stub_response(stubbed_hash) + + provider = TestProvider.new(nil, RubyLLM::Test) + response = provider.complete([], tools: [], temperature: 0.5, model: "test-model", params: {}, headers: {}) + + assert_kind_of Message, response + assert_equal stubbed_hash.to_json, response.content + end + end + + class TestProviderLastCallTest < Minitest::Test + def setup + RubyLLM::Test.reset + RubyLLM::Test.stub_response("stubbed response") + + initialize_arguments + provider = TestProvider.new(nil, RubyLLM::Test) + provider.complete(@messages, tools: @tools, temperature: @temperature, model: @model, params: @params, + headers: @headers, schema: @schema, thinking: @thinking, tool_prefs: @tool_prefs) + + @last_call = provider.last_call + end + + def test_last_call_captures_messages + assert_equal @messages, @last_call.messages + end + + def test_last_call_captures_tools + assert_equal @tools, @last_call.tools + end + + def test_last_call_captures_temperature + assert_equal @temperature, @last_call.temperature + end + + def test_last_call_captures_model + assert_equal @model, @last_call.model + end + + def test_last_call_captures_params + assert_equal @params, @last_call.params + end + + def test_last_call_captures_headers + assert_equal @headers, @last_call.headers + end + + def test_last_call_captures_schema + assert_equal @schema, @last_call.schema + end + + def test_last_call_captures_thinking + assert_equal @thinking, @last_call.thinking + end + + def test_last_call_captures_tool_prefs + assert_equal @tool_prefs, @last_call.tool_prefs + end + + private + + def initialize_arguments + @messages = [ Message.new(role: :user, content: "Hello") ] + @tools = %w[tool1 tool2] + @temperature = 0.7 + @model = "test-model" + @params = { param1: "value1" } + @headers = { "Authorization" => "Bearer token" } + @schema = { type: "object" } + @thinking = "thinking process" + @tool_prefs = { prefer_tool1: true } + end + end + end +end diff --git a/test/ruby_llm/test_test.rb b/test/ruby_llm/test_test.rb index 5f11544..bf79376 100644 --- a/test/ruby_llm/test_test.rb +++ b/test/ruby_llm/test_test.rb @@ -4,8 +4,42 @@ module RubyLLM class TestTest < Minitest::Test - def test_that_it_has_a_version_number - refute_nil ::RubyLLM::Test::VERSION + def test_stub_response + RubyLLM::Test.reset + RubyLLM::Test.stub_response("test response") + + assert_equal "test response", RubyLLM::Test.next_response + end + + def test_stub_responses + RubyLLM::Test.reset + RubyLLM::Test.stub_responses("response 1", "response 2") + + assert_equal "response 1", RubyLLM::Test.next_response + assert_equal "response 2", RubyLLM::Test.next_response + end + + def test_with_responses + RubyLLM::Test.reset + RubyLLM::Test.stub_response("initial response") + + RubyLLM::Test.with_responses("temp response 1", "temp response 2") do + assert_equal "temp response 1", RubyLLM::Test.next_response + assert_equal "temp response 2", RubyLLM::Test.next_response + end + + # Ensure original responses are restored after the block + assert_equal "initial response", RubyLLM::Test.next_response + end + + def test_responses_empty + RubyLLM::Test.reset + + assert_predicate RubyLLM::Test, :responses_empty? + + RubyLLM::Test.stub_response("not empty anymore") + + refute_predicate RubyLLM::Test, :responses_empty? end end end diff --git a/test/test_helper.rb b/test/test_helper.rb index cca02d9..0e40b00 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -1,6 +1,11 @@ # frozen_string_literal: true -$LOAD_PATH.unshift File.expand_path("../lib", __dir__) -require "ruby_llm/test" +require "simplecov" + +SimpleCov.start do + add_filter %r{^/test/} + enable_coverage :branch +end +require "ruby_llm/test" require "minitest/autorun"