discourse-ai/spec/lib/personas/tools/javascript_evaluator_spec.rb
Roman Rizzi 30242a27e6
REFACTOR: Move personas into its own module. (#1233)
This change moves all the personas code into its own module. We want to treat them as a building block features can built on top of, same as `Completions::Llm`.

The code to title a message was moved from `Bot` to `Playground`.
2025-03-31 14:42:33 -03:00

73 lines
2.3 KiB
Ruby

# frozen_string_literal: true
RSpec.describe DiscourseAi::Personas::Tools::JavascriptEvaluator do
fab!(:llm_model)
let(:bot_user) { DiscourseAi::AiBot::EntryPoint.find_user_from_model(llm_model.name) }
let(:llm) { DiscourseAi::Completions::Llm.proxy("custom:#{llm_model.id}") }
let(:progress_blk) { Proc.new {} }
before { SiteSetting.ai_bot_enabled = true }
describe "#invoke" do
it "successfully evaluates a simple JavaScript expression" do
evaluator = described_class.new({ script: "2 + 2" }, bot_user: bot_user, llm: llm)
result = evaluator.invoke(&progress_blk)
expect(result[:result]).to eq(4)
end
it "handles JavaScript execution timeout" do
evaluator = described_class.new({ script: "while(true){}" }, bot_user: bot_user, llm: llm)
evaluator.timeout = 5
result = evaluator.invoke(&progress_blk)
expect(result[:error]).to include("JavaScript execution timed out")
end
it "handles JavaScript memory limit exceeded" do
evaluator =
described_class.new(
{ script: "var a = new Array(10000); while(true) { a = a.concat(new Array(10000)) }" },
bot_user: bot_user,
llm: llm,
)
evaluator.max_memory = 10_000
result = evaluator.invoke(&progress_blk)
expect(result[:error]).to include("JavaScript execution exceeded memory limit")
end
it "returns error for invalid JavaScript syntax" do
evaluator = described_class.new({ script: "const x =;" }, bot_user: bot_user, llm: llm)
result = evaluator.invoke(&progress_blk)
expect(result[:error]).to include("JavaScript execution error: ")
end
it "truncates long results" do
evaluator =
described_class.new(
{ script: "const x = 'zxn'.repeat(10000); x + 'Z';" },
bot_user: bot_user,
llm: llm,
)
result = evaluator.invoke(&progress_blk)
expect(result[:result]).not_to include("Z")
end
it "returns result for more complex JavaScript" do
evaluator =
described_class.new(
{ script: "const x = [1, 2, 3, 4].map(n => n * 2); x.reduce((a, b) => a + b, 0);" },
bot_user: bot_user,
llm: llm,
)
result = evaluator.invoke(&progress_blk)
expect(result[:result]).to eq(20)
end
end
end