1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
|
# frozen_string_literal: true
RSpec.describe "create_file tool" do
let(:worktree_path) { Dir.mktmpdir("create-file-test") }
let(:context) { { worktree_path: } }
let(:registry) { Dispatch::Tools::Registry.new }
before { Dispatch::Tool::Files.register(registry) }
after { FileUtils.remove_entry(worktree_path) }
subject(:tool) { registry.get("create_file") }
describe "creating a new file" do
it "creates a file with the given content" do
result = tool.call({ "path" => "new_file.rb", "content" => "puts 'hello'" }, context:)
expect(result.success?).to be true
expect(File.read(File.join(worktree_path, "new_file.rb"))).to eq("puts 'hello'")
end
it "returns a confirmation message" do
result = tool.call({ "path" => "created.txt", "content" => "content" }, context:)
expect(result.success?).to be true
expect(result.output).to include("created.txt")
end
it "creates parent directories as needed" do
result = tool.call({ "path" => "deep/nested/dir/file.txt", "content" => "deep content" }, context:)
expect(result.success?).to be true
expect(File.read(File.join(worktree_path, "deep/nested/dir/file.txt"))).to eq("deep content")
end
end
describe "error cases" do
it "returns failure when the file already exists" do
file_path = File.join(worktree_path, "existing.txt")
File.write(file_path, "original")
result = tool.call({ "path" => "existing.txt", "content" => "overwrite attempt" }, context:)
expect(result.failure?).to be true
expect(result.error).to match(/already exists/i)
expect(File.read(file_path)).to eq("original")
end
it "returns failure when the path escapes the sandbox" do
result = tool.call({ "path" => "../../../tmp/evil.txt", "content" => "bad" }, context:)
expect(result.failure?).to be true
expect(result.error).to match(/sandbox|outside/i)
end
end
describe "parameter validation" do
it "requires the path parameter" do
result = tool.call({ "content" => "data" }, context:)
expect(result.failure?).to be true
end
it "requires the content parameter" do
result = tool.call({ "path" => "file.txt" }, context:)
expect(result.failure?).to be true
end
end
end
|