aboutsummaryrefslogtreecommitdiff
path: root/test/functional/lua/ui_spec.lua
blob: d69e893c96c945108204c8f576e07b098246b230 (plain) (blame)
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
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
local t = require('test.testutil')
local n = require('test.functional.testnvim')()

local eq = t.eq
local ok = t.ok
local exec_lua = n.exec_lua
local clear = n.clear
local feed = n.feed
local eval = n.eval
local is_ci = t.is_ci
local is_os = t.is_os
local poke_eventloop = n.poke_eventloop

describe('vim.ui', function()
  before_each(function()
    clear()
  end)

  describe('select()', function()
    it('can select an item', function()
      local result = exec_lua [[
        local items = {
          { name = 'Item 1' },
          { name = 'Item 2' },
        }
        local opts = {
          format_item = function(entry)
            return entry.name
          end
        }
        local selected
        local cb = function(item)
          selected = item
        end
        -- inputlist would require input and block the test;
        local choices
        vim.fn.inputlist = function(x)
          choices = x
          return 1
        end
        vim.ui.select(items, opts, cb)
        vim.wait(100, function() return selected ~= nil end)
        return {selected, choices}
      ]]
      eq({ name = 'Item 1' }, result[1])
      eq({
        'Select one of:',
        '1: Item 1',
        '2: Item 2',
      }, result[2])
    end)
  end)

  describe('input()', function()
    it('can input text', function()
      local result = exec_lua [[
        local opts = {
            prompt = 'Input: ',
        }
        local input
        local cb = function(item)
          input = item
        end
        -- input would require input and block the test;
        local prompt
        vim.fn.input = function(opts)
          prompt = opts.prompt
          return "Inputted text"
        end
        vim.ui.input(opts, cb)
        vim.wait(100, function() return input ~= nil end)
        return {input, prompt}
      ]]
      eq('Inputted text', result[1])
      eq('Input: ', result[2])
    end)

    it('can input text on nil opt', function()
      feed(':lua vim.ui.input(nil, function(input) result = input end)<cr>')
      eq('', eval('v:errmsg'))
      feed('Inputted text<cr>')
      eq('Inputted text', exec_lua('return result'))
    end)

    it('can input text on {} opt', function()
      feed(':lua vim.ui.input({}, function(input) result = input end)<cr>')
      eq('', eval('v:errmsg'))
      feed('abcdefg<cr>')
      eq('abcdefg', exec_lua('return result'))
    end)

    it('can input empty text #18144', function()
      feed(':lua vim.ui.input({}, function(input) result = input end)<cr>')
      feed('<cr>')
      eq('', exec_lua('return result'))
    end)

    it('can input empty text with cancelreturn opt #18144', function()
      feed(':lua vim.ui.input({ cancelreturn = "CANCEL" }, function(input) result = input end)<cr>')
      feed('<cr>')
      eq('', exec_lua('return result'))
    end)

    it('can return nil when aborted with ESC #18144', function()
      feed(':lua result = "on_confirm not called"<cr>')
      feed(':lua vim.ui.input({}, function(input) result = input end)<cr>')
      feed('Inputted Text<esc>')
      -- Note: When `result == nil`, exec_lua('returns result') returns vim.NIL
      eq(true, exec_lua('return (nil == result)'))
    end)

    it('can return opts.cacelreturn when aborted with ESC with cancelreturn opt #18144', function()
      feed(':lua result = "on_confirm not called"<cr>')
      feed(':lua vim.ui.input({ cancelreturn = "CANCEL" }, function(input) result = input end)<cr>')
      feed('Inputted Text<esc>')
      eq('CANCEL', exec_lua('return result'))
    end)

    it('can return nil when interrupted with Ctrl-C #18144', function()
      feed(':lua result = "on_confirm not called"<cr>')
      feed(':lua vim.ui.input({}, function(input) result = input end)<cr>')
      poke_eventloop() -- This is needed because Ctrl-C flushes input
      feed('Inputted Text<c-c>')
      eq(true, exec_lua('return (nil == result)'))
    end)

    it(
      'can return the identical object when an arbitrary opts.cancelreturn object is given',
      function()
        feed(':lua fn = function() return 42 end<CR>')
        eq(42, exec_lua('return fn()'))
        feed(':lua vim.ui.input({ cancelreturn = fn }, function(input) result = input end)<cr>')
        feed('cancel<esc>')
        eq(true, exec_lua('return (result == fn)'))
        eq(42, exec_lua('return result()'))
      end
    )
  end)

  describe('open()', function()
    it('validation', function()
      if is_os('win') or not is_ci('github') then
        exec_lua [[vim.system = function() return { wait=function() return { code=3 } end } end]]
      end
      if not is_os('bsd') then
        local rv =
          exec_lua [[local cmd = vim.ui.open('non-existent-file'); return cmd:wait(100).code]]
        ok(type(rv) == 'number' and rv ~= 0, 'nonzero exit code', rv)
      end

      exec_lua [[
        vim.fn.has = function() return 0 end
        vim.fn.executable = function() return 0 end
      ]]
      eq(
        'vim.ui.open: no handler found (tried: wslview, explorer.exe, xdg-open)',
        exec_lua [[local _, err = vim.ui.open('foo') ; return err]]
      )
    end)
  end)
end)