| 
 | 1 | +-- Verifies that rejecting a new-file diff with an empty buffer left open does not crash,  | 
 | 2 | +-- and a subsequent write (diff setup) works again.  | 
 | 3 | +require("tests.busted_setup")  | 
 | 4 | + | 
 | 5 | +describe("New file diff: reject then reopen", function()  | 
 | 6 | +  local diff  | 
 | 7 | + | 
 | 8 | +  before_each(function()  | 
 | 9 | +    -- Fresh vim mock state  | 
 | 10 | +    if vim and vim._mock and vim._mock.reset then  | 
 | 11 | +      vim._mock.reset()  | 
 | 12 | +    end  | 
 | 13 | + | 
 | 14 | +    -- Minimal logger stub  | 
 | 15 | +    package.loaded["claudecode.logger"] = {  | 
 | 16 | +      debug = function() end,  | 
 | 17 | +      error = function() end,  | 
 | 18 | +      info = function() end,  | 
 | 19 | +      warn = function() end,  | 
 | 20 | +    }  | 
 | 21 | + | 
 | 22 | +    -- Reload diff module cleanly  | 
 | 23 | +    package.loaded["claudecode.diff"] = nil  | 
 | 24 | +    diff = require("claudecode.diff")  | 
 | 25 | + | 
 | 26 | +    -- Setup config on diff  | 
 | 27 | +    diff.setup({  | 
 | 28 | +      diff_opts = {  | 
 | 29 | +        layout = "vertical",  | 
 | 30 | +        open_in_new_tab = false,  | 
 | 31 | +        keep_terminal_focus = false,  | 
 | 32 | +        on_new_file_reject = "keep_empty", -- default behavior  | 
 | 33 | +      },  | 
 | 34 | +      terminal = {},  | 
 | 35 | +    })  | 
 | 36 | + | 
 | 37 | +    -- Create an empty unnamed buffer and set it in current window so _create_diff_view_from_window reuses it  | 
 | 38 | +    local empty_buf = vim.api.nvim_create_buf(false, true)  | 
 | 39 | +    -- Ensure name is empty and 'modified' is false  | 
 | 40 | +    vim.api.nvim_buf_set_name(empty_buf, "")  | 
 | 41 | +    vim.api.nvim_buf_set_option(empty_buf, "modified", false)  | 
 | 42 | + | 
 | 43 | +    -- Make current window use this empty buffer  | 
 | 44 | +    local current_win = vim.api.nvim_get_current_win()  | 
 | 45 | +    vim.api.nvim_win_set_buf(current_win, empty_buf)  | 
 | 46 | +  end)  | 
 | 47 | + | 
 | 48 | +  it("should reuse empty buffer for new-file diff, not delete it on reject, and allow reopening", function()  | 
 | 49 | +    local tab_name = "✻ [TestNewFile] new.lua ⧉"  | 
 | 50 | +    local params = {  | 
 | 51 | +      old_file_path = "/nonexistent/path/to/new.lua", -- ensure new-file scenario  | 
 | 52 | +      new_file_path = "/tmp/new.lua",  | 
 | 53 | +      new_file_contents = "print('hello')\n",  | 
 | 54 | +      tab_name = tab_name,  | 
 | 55 | +    }  | 
 | 56 | + | 
 | 57 | +    -- Track current window buffer (the reused empty buffer)  | 
 | 58 | +    local target_win = vim.api.nvim_get_current_win()  | 
 | 59 | +    local reused_buf = vim.api.nvim_win_get_buf(target_win)  | 
 | 60 | +    assert.is_true(vim.api.nvim_buf_is_valid(reused_buf))  | 
 | 61 | + | 
 | 62 | +    -- 1) Setup the diff (should reuse the empty buffer)  | 
 | 63 | +    local setup_ok, setup_err = pcall(function()  | 
 | 64 | +      diff._setup_blocking_diff(params, function() end)  | 
 | 65 | +    end)  | 
 | 66 | +    assert.is_true(setup_ok, "Diff setup failed unexpectedly: " .. tostring(setup_err))  | 
 | 67 | + | 
 | 68 | +    -- Verify state registered (ownership may vary based on window conditions)  | 
 | 69 | +    local active = diff._get_active_diffs()  | 
 | 70 | +    assert.is_table(active[tab_name])  | 
 | 71 | +    -- Ensure the original buffer reference exists and is valid  | 
 | 72 | +    assert.is_true(vim.api.nvim_buf_is_valid(active[tab_name].original_buffer))  | 
 | 73 | + | 
 | 74 | +    -- 2) Reject the diff; cleanup should NOT delete the reused empty buffer  | 
 | 75 | +    diff._resolve_diff_as_rejected(tab_name)  | 
 | 76 | + | 
 | 77 | +    -- After reject, the diff state should be removed  | 
 | 78 | +    local active_after_reject = diff._get_active_diffs()  | 
 | 79 | +    assert.is_nil(active_after_reject[tab_name])  | 
 | 80 | + | 
 | 81 | +    -- The reused buffer should still be valid (not deleted)  | 
 | 82 | +    assert.is_true(vim.api.nvim_buf_is_valid(reused_buf))  | 
 | 83 | + | 
 | 84 | +    -- 3) Setup the diff again with the same conditions; should succeed  | 
 | 85 | +    local setup_ok2, setup_err2 = pcall(function()  | 
 | 86 | +      diff._setup_blocking_diff(params, function() end)  | 
 | 87 | +    end)  | 
 | 88 | +    assert.is_true(setup_ok2, "Second diff setup failed unexpectedly: " .. tostring(setup_err2))  | 
 | 89 | + | 
 | 90 | +    -- Verify new state exists again  | 
 | 91 | +    local active_again = diff._get_active_diffs()  | 
 | 92 | +    assert.is_table(active_again[tab_name])  | 
 | 93 | + | 
 | 94 | +    -- Clean up to avoid affecting other tests  | 
 | 95 | +    diff._cleanup_diff_state(tab_name, "test cleanup")  | 
 | 96 | +  end)  | 
 | 97 | +end)  | 
0 commit comments