UNPKG

neovim

Version:

Nvim msgpack API client and remote plugin provider

385 lines (384 loc) 20.4 kB
"use strict"; var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); __setModuleDefault(result, mod); return result; }; var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); } return new (P || (P = Promise))(function (resolve, reject) { function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); } step((generator = generator.apply(thisArg, _arguments || [])).next()); }); }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const node_assert_1 = __importDefault(require("node:assert")); const expect_1 = require("expect"); const jestMock = __importStar(require("jest-mock")); const testUtil = __importStar(require("../testUtil")); function wait(ms) { return new Promise(resolve => { setTimeout(() => { resolve(); }, ms); }); } describe('Buffer API', () => { let nvim; // utility to allow each test to be run in its // own buffer function withBuffer(lines, test) { return () => __awaiter(this, void 0, void 0, function* () { yield nvim.command('new!'); const buffer = yield nvim.buffer; if (lines) { yield buffer.replace(lines, 0); } yield test(buffer); yield nvim.command(`bd! ${buffer.id}`); }); } before(() => __awaiter(void 0, void 0, void 0, function* () { [, nvim] = testUtil.startNvim(); })); after(() => { testUtil.stopNvim(); }); it('gets the current buffer', withBuffer([], (buffer) => __awaiter(void 0, void 0, void 0, function* () { (0, expect_1.expect)(buffer).toBeInstanceOf(nvim.Buffer); }))); it('get bufnr by id', withBuffer([], (buffer) => __awaiter(void 0, void 0, void 0, function* () { const bufnr = yield nvim.call('bufnr', ['%']); (0, expect_1.expect)(buffer.id).toBe(bufnr); }))); describe('Normal API calls', () => { it('gets changedtick of buffer', withBuffer([], (buffer) => __awaiter(void 0, void 0, void 0, function* () { const initial = yield buffer.changedtick; // insert a line buffer.append('hi'); (0, expect_1.expect)(yield buffer.changedtick).toBe(initial + 1); // clear buffer buffer.remove(0, -1, false); (0, expect_1.expect)(yield buffer.changedtick).toBe(initial + 2); }))); it('sets/gets the current buffer name', () => __awaiter(void 0, void 0, void 0, function* () { (yield nvim.buffers)[0].name = 'hello.txt'; const name = yield (yield nvim.buffers)[0].name; (0, expect_1.expect)(name).toMatch('hello.txt'); })); it('is a valid buffer', withBuffer([], (buffer) => __awaiter(void 0, void 0, void 0, function* () { (0, expect_1.expect)(yield buffer.valid).toBe(true); }))); it('sets current buffer name to "foo.txt"', withBuffer([], (buffer) => __awaiter(void 0, void 0, void 0, function* () { // eslint-disable-next-line no-param-reassign buffer.name = 'foo.txt'; (0, expect_1.expect)(yield buffer.name).toMatch('foo.txt'); // eslint-disable-next-line no-param-reassign buffer.name = 'test2.txt'; (0, expect_1.expect)(yield buffer.name).toMatch('test2.txt'); }))); it('can replace first line of buffer with a string', withBuffer(['foo'], (buffer) => __awaiter(void 0, void 0, void 0, function* () { buffer.replace('test', 0); (0, expect_1.expect)(yield buffer.lines).toEqual(['test']); }))); it('can insert lines at beginning of buffer', withBuffer(['test'], (buffer) => __awaiter(void 0, void 0, void 0, function* () { yield buffer.insert(['test', 'foo'], 0); (0, expect_1.expect)(yield buffer.lines).toEqual(['test', 'foo', 'test']); }))); it('replaces the right lines', withBuffer(['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'], (buffer) => __awaiter(void 0, void 0, void 0, function* () { yield buffer.replace(['a', 'b', 'c'], 2); (0, expect_1.expect)(yield buffer.lines).toEqual(['0', '1', 'a', 'b', 'c', '5', '6', '7', '8', '9']); }))); it('inserts line at index 2', withBuffer(['test', 'bar', 'bar', 'bar'], (buffer) => __awaiter(void 0, void 0, void 0, function* () { buffer.insert(['foo'], 2); (0, expect_1.expect)(yield buffer.lines).toEqual(['test', 'bar', 'foo', 'bar', 'bar']); }))); it('removes last 2 lines', withBuffer(['test', 'bar', 'foo', 'a', 'b'], (buffer) => __awaiter(void 0, void 0, void 0, function* () { buffer.remove(-3, -1, true); (0, expect_1.expect)(yield buffer.lines).toEqual(['test', 'bar', 'foo']); }))); it('checks if buffer is loaded', () => __awaiter(void 0, void 0, void 0, function* () { yield nvim.command('new'); const buffer = yield nvim.buffer; (0, expect_1.expect)(yield buffer.loaded).toBe(true); yield nvim.command('bunload!'); (0, expect_1.expect)(yield buffer.loaded).toBe(false); })); it('gets byte offset for a line', withBuffer(['test', 'bar', ''], (buffer) => __awaiter(void 0, void 0, void 0, function* () { (0, expect_1.expect)(yield buffer.getOffset(0)).toEqual(0); (0, expect_1.expect)(yield buffer.getOffset(1)).toEqual(5); // test\n (0, expect_1.expect)(yield buffer.getOffset(2)).toEqual(9); // test\n + bar\n (0, expect_1.expect)(yield buffer.getOffset(3)).toEqual(10); // test\n + bar\n + \n (0, expect_1.expect)(buffer.getOffset(4)).rejects.toThrow(); }))); it('returns -1 for byte offset of unloaded buffer', () => __awaiter(void 0, void 0, void 0, function* () { yield nvim.command('new'); yield nvim.command('bunload!'); const buffer = yield nvim.buffer; (0, expect_1.expect)(yield buffer.getOffset(0)).toEqual(-1); })); it('append lines to end of buffer', withBuffer(['test', 'bar', 'foo'], (buffer) => __awaiter(void 0, void 0, void 0, function* () { yield buffer.append(['test', 'test']); (0, expect_1.expect)(yield buffer.lines).toEqual(['test', 'bar', 'foo', 'test', 'test']); }))); it('can clear the buffer', withBuffer(['foo'], (buffer) => __awaiter(void 0, void 0, void 0, function* () { buffer.remove(0, -1, true); // One empty line (0, expect_1.expect)(yield buffer.length).toEqual(1); (0, expect_1.expect)(yield buffer.lines).toEqual(['']); }))); it('changes buffer options', withBuffer([], (buffer) => __awaiter(void 0, void 0, void 0, function* () { const initial = yield buffer.getOption('copyindent'); buffer.setOption('copyindent', true); (0, expect_1.expect)(yield buffer.getOption('copyindent')).toBe(true); buffer.setOption('copyindent', false); (0, expect_1.expect)(yield buffer.getOption('copyindent')).toBe(false); (0, node_assert_1.default)(initial !== undefined); // Restore option buffer.setOption('copyindent', initial); (0, expect_1.expect)(yield buffer.getOption('copyindent')).toBe(initial); }))); it('returns null if variable is not found', withBuffer([], (buffer) => __awaiter(void 0, void 0, void 0, function* () { const test = yield buffer.getVar('test'); (0, expect_1.expect)(test).toBe(null); }))); it('can set and delete a b: variable to an object', withBuffer([], (buffer) => __awaiter(void 0, void 0, void 0, function* () { buffer.setVar('test', { foo: 'testValue' }); (0, expect_1.expect)(yield buffer.getVar('test')).toEqual({ foo: 'testValue' }); (0, expect_1.expect)(yield nvim.eval('b:test')).toEqual({ foo: 'testValue' }); buffer.deleteVar('test'); (0, expect_1.expect)(yield nvim.eval('exists("b:test")')).toBe(0); (0, expect_1.expect)(yield buffer.getVar('test')).toBe(null); }))); it('can get list of commands', () => __awaiter(void 0, void 0, void 0, function* () { (0, expect_1.expect)(yield nvim.buffer.commands).toEqual({}); })); it('sets virtual text and clears namespace', withBuffer(['test'], (buffer) => __awaiter(void 0, void 0, void 0, function* () { const ns = yield nvim.createNamespace(); yield buffer.setVirtualText(ns, 0, [['annotation', '']]); yield buffer.clearNamespace({ nsId: ns }); }))); // TODO: How do we run integration tests for add/clear highlights? and get mark }); describe('Chainable API calls', () => { it('sets/gets the current buffer name using api chaining', () => __awaiter(void 0, void 0, void 0, function* () { const buffer = yield nvim.buffer; buffer.name = 'goodbye.txt'; (0, expect_1.expect)(yield nvim.buffer.name).toMatch('goodbye.txt'); })); it('can chain calls from Base class i.e. getOption', () => __awaiter(void 0, void 0, void 0, function* () { const buffer = yield nvim.buffer; const initial = yield buffer.getOption('copyindent'); buffer.setOption('copyindent', true); (0, expect_1.expect)(yield buffer.getOption('copyindent')).toBe(true); buffer.setOption('copyindent', false); (0, expect_1.expect)(yield buffer.getOption('copyindent')).toBe(false); (0, node_assert_1.default)(initial !== undefined); // Restore option buffer.setOption('copyindent', initial); (0, expect_1.expect)(yield buffer.getOption('copyindent')).toBe(initial); })); it('sets current buffer name to "bar.js" using api chaining', () => __awaiter(void 0, void 0, void 0, function* () { const buffer = yield nvim.buffer; buffer.name = 'bar.js'; (0, expect_1.expect)(yield buffer.name).toMatch('bar.js'); buffer.name = 'test2.js'; (0, expect_1.expect)(yield buffer.name).toMatch('test2.js'); })); it('can replace first line of nvim.buffer with a string', withBuffer([], () => __awaiter(void 0, void 0, void 0, function* () { const buffer = yield nvim.buffer; yield buffer.replace('test', 0); (0, expect_1.expect)(yield buffer.lines).toEqual(['test']); }))); it('replaces the right lines', withBuffer(['0', '1', '2', '3', '4', '5', '6', '7', '8', '9'], () => __awaiter(void 0, void 0, void 0, function* () { const buffer = yield nvim.buffer; yield buffer.replace(['a', 'b', 'c'], 2); (0, expect_1.expect)(yield buffer.lines).toEqual(['0', '1', 'a', 'b', 'c', '5', '6', '7', '8', '9']); }))); it('can insert lines at beginning of buffer', withBuffer(['test'], () => __awaiter(void 0, void 0, void 0, function* () { const buffer = yield nvim.buffer; yield buffer.insert(['test', 'foo'], 0); (0, expect_1.expect)(yield buffer.lines).toEqual(['test', 'foo', 'test']); }))); it('can replace nvim.buffer starting at line 1', withBuffer(['test', 'foo'], () => __awaiter(void 0, void 0, void 0, function* () { const buffer = yield nvim.buffer; yield buffer.replace(['bar', 'bar', 'bar'], 1); (0, expect_1.expect)(yield buffer.lines).toEqual(['test', 'bar', 'bar', 'bar']); }))); it('inserts line at index 2', withBuffer(['test', 'bar', 'bar', 'bar'], () => __awaiter(void 0, void 0, void 0, function* () { const buffer = yield nvim.buffer; yield buffer.insert(['foo'], 2); (0, expect_1.expect)(yield buffer.lines).toEqual(['test', 'bar', 'foo', 'bar', 'bar']); }))); it('removes last 2 lines', withBuffer(['test', 'bar', 'foo', 'a', 'b'], () => __awaiter(void 0, void 0, void 0, function* () { const buffer = yield nvim.buffer; yield buffer.remove(-3, -1, true); (0, expect_1.expect)(yield buffer.lines).toEqual(['test', 'bar', 'foo']); }))); it('append lines to end of buffer', withBuffer(['test', 'bar', 'foo'], () => __awaiter(void 0, void 0, void 0, function* () { const buffer = yield nvim.buffer; yield buffer.append(['test', 'test']); (0, expect_1.expect)(yield buffer.lines).toEqual(['test', 'bar', 'foo', 'test', 'test']); }))); it('can clear the buffer', withBuffer(['foo'], () => __awaiter(void 0, void 0, void 0, function* () { const buffer = yield nvim.buffer; yield buffer.remove(0, -1, true); // One empty line (0, expect_1.expect)(yield buffer.length).toEqual(1); (0, expect_1.expect)(yield buffer.lines).toEqual(['']); }))); }); }); describe('Buffer event updates', () => { let nvim; before(() => __awaiter(void 0, void 0, void 0, function* () { [, nvim] = testUtil.startNvim(); })); after(() => { testUtil.stopNvim(); }); beforeEach(() => __awaiter(void 0, void 0, void 0, function* () { yield (yield nvim.buffer).remove(0, -1, true); })); it('can listen and unlisten', () => __awaiter(void 0, void 0, void 0, function* () { const buffer = yield nvim.buffer; const mock = jestMock.fn(); const unlisten = buffer.listen('lines', mock); yield buffer.insert(['bar'], 1); (0, expect_1.expect)(mock).toHaveBeenCalledTimes(1); unlisten(); yield buffer.insert(['bar'], 1); (0, expect_1.expect)(mock).toHaveBeenCalledTimes(1); })); it('can reattach for buffer events', () => __awaiter(void 0, void 0, void 0, function* () { const buffer = yield nvim.buffer; let unlisten = buffer.listen('lines', jestMock.fn()); unlisten(); yield wait(10); const mock = jestMock.fn(); unlisten = buffer.listen('lines', mock); yield buffer.insert(['bar'], 1); (0, expect_1.expect)(mock).toHaveBeenCalledTimes(1); unlisten(); })); it('should return attached state', () => __awaiter(void 0, void 0, void 0, function* () { const buffer = yield nvim.buffer; const unlisten = buffer.listen('lines', jestMock.fn()); yield wait(30); let attached = buffer.isAttached; (0, expect_1.expect)(attached).toBe(true); unlisten(); yield wait(30); attached = buffer.isAttached; (0, expect_1.expect)(attached).toBe(false); })); it('only bind once for the same event and handler ', () => __awaiter(void 0, void 0, void 0, function* () { const buffer = yield nvim.buffer; const mock = jestMock.fn(); buffer.listen('lines', mock); buffer.listen('lines', mock); yield buffer.insert(['bar'], 1); (0, expect_1.expect)(mock).toHaveBeenCalledTimes(1); })); it('can use `buffer.unlisten` to unlisten', () => __awaiter(void 0, void 0, void 0, function* () { const buffer = yield nvim.buffer; const mock = jestMock.fn(); buffer.listen('lines', mock); yield buffer.insert(['bar'], 1); (0, expect_1.expect)(mock).toHaveBeenCalledTimes(1); buffer.unlisten('lines', mock); yield buffer.insert(['bar'], 1); (0, expect_1.expect)(mock).toHaveBeenCalledTimes(1); })); it('listens to line updates', () => __awaiter(void 0, void 0, void 0, function* () { const buffer = yield nvim.buffer; const bufferName = yield buffer.name; yield buffer.insert(['test', 'foo'], 0); const promise = new Promise(resolve => { const unlisten = buffer.listen('lines', (currentBuffer, tick, start, end, data) => __awaiter(void 0, void 0, void 0, function* () { (0, expect_1.expect)(yield currentBuffer.name).toBe(bufferName); (0, expect_1.expect)(start).toBe(1); (0, expect_1.expect)(end).toBe(1); (0, expect_1.expect)(data).toEqual(['bar']); unlisten(); resolve(); })); }); yield buffer.insert(['bar'], 1); yield promise; })); it('has listener on multiple buffers ', () => __awaiter(void 0, void 0, void 0, function* () { yield nvim.command('new!'); const buffers = yield nvim.buffers; const foo = jestMock.fn(); const bar = jestMock.fn(); buffers[0].listen('lines', foo); buffers[1].listen('lines', bar); yield (yield nvim.buffer).insert(['bar'], 1); (0, expect_1.expect)(foo).toHaveBeenCalledTimes(0); (0, expect_1.expect)(bar).toHaveBeenCalledTimes(1); yield nvim.command('q!'); yield (yield nvim.buffer).insert(['foo'], 0); (0, expect_1.expect)(foo).toHaveBeenCalledTimes(1); (0, expect_1.expect)(bar).toHaveBeenCalledTimes(1); buffers[0].unlisten('lines', foo); buffers[1].unlisten('lines', bar); })); it('has multiple listeners for same event, on same buffer', () => __awaiter(void 0, void 0, void 0, function* () { yield nvim.command('new!'); const buffer = yield nvim.buffer; const foo = jestMock.fn(); const bar = jestMock.fn(); const unlisten1 = buffer.listen('lines', foo); const unlisten2 = buffer.listen('lines', bar); yield buffer.insert(['bar'], 1); (0, expect_1.expect)(foo).toHaveBeenCalledTimes(1); (0, expect_1.expect)(bar).toHaveBeenCalledTimes(1); unlisten2(); yield buffer.insert(['foo'], 0); (0, expect_1.expect)(foo).toHaveBeenCalledTimes(2); (0, expect_1.expect)(bar).toHaveBeenCalledTimes(1); unlisten1(); yield nvim.command('q!'); })); it('has multiple listeners for different events, on same buffer', () => __awaiter(void 0, void 0, void 0, function* () { yield nvim.command('new!'); const buffer = yield nvim.buffer; const foo = jestMock.fn(); const bar = jestMock.fn(); const unlisten1 = buffer.listen('lines', foo); const unlisten2 = buffer.listen('changedtick', bar); yield buffer.insert(['bar'], 1); (0, expect_1.expect)(foo).toHaveBeenCalledTimes(1); (0, expect_1.expect)(bar).toHaveBeenCalledTimes(1); unlisten2(); yield buffer.insert(['foo'], 0); (0, expect_1.expect)(foo).toHaveBeenCalledTimes(2); (0, expect_1.expect)(bar).toHaveBeenCalledTimes(1); unlisten1(); yield nvim.command('q!'); })); });