From b2b025d1adad9b135413a1ccfba0762192889833 Mon Sep 17 00:00:00 2001
From: Julian Berman <Julian@GrayVines.com>
Date: Sun, 24 Nov 2024 18:51:04 -0500
Subject: [PATCH] WIP

---
 .busted                  | 19 +++++++++++++++++++
 .github/workflows/ci.yml |  8 ++++++--
 .gitignore               |  2 +-
 justfile                 | 24 ++++++++++--------------
 lean.nvim-scm-1.rockspec |  2 ++
 spec/fixtures.lua        |  2 ++
 spec/nvim-shim           |  8 ++++++++
 spec/spec_helper.lua     | 25 +++++++++++++++++++++++++
 8 files changed, 73 insertions(+), 17 deletions(-)
 create mode 100644 .busted
 create mode 100755 spec/nvim-shim
 create mode 100644 spec/spec_helper.lua

diff --git a/.busted b/.busted
new file mode 100644
index 00000000..657baaa6
--- /dev/null
+++ b/.busted
@@ -0,0 +1,19 @@
+return {
+  _all = {
+    helper = 'spec/spec_helper.lua',
+    lpath = 'lua/?.lua;lua/?/init.lua',
+    lua = './spec/nvim-shim',
+  },
+  default = {
+    coverage = false,
+    verbose = false
+  },
+  verbose = {
+    coverage = false,
+    verbose = true
+  },
+  coverage = {
+    coverage = true,
+    verbose = true
+  },
+}
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index cbc515b1..2507f2eb 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -27,6 +27,12 @@ jobs:
       - uses: actions/checkout@v4
         with:
           persist-credentials: false
+
+      - uses: leafo/gh-actions-lua@v10
+        with:
+          luaVersion: "luajit-openresty"
+      - uses: leafo/gh-actions-luarocks@v4
+
       - name: Install Neovim
         uses: rhysd/action-setup-vim@v1
         with:
@@ -37,8 +43,6 @@ jobs:
       - uses: extractions/setup-just@v2
       - name: Run tests
         run: just test
-        env:
-          TEST_SEQUENTIAL: 1
 
   release:
     if: github.event_name == 'push' && startsWith(github.event.ref, 'refs/tags/v')
diff --git a/.gitignore b/.gitignore
index 1c57489b..cb387569 100644
--- a/.gitignore
+++ b/.gitignore
@@ -8,7 +8,7 @@ demo.mp4
 
 /luapath
 /packpath
-/pack
+/.isolated_config*
 
 /.tests
 /lua/tests/fixtures/example-project/build
diff --git a/justfile b/justfile
index 249f81f0..a7980ee0 100644
--- a/justfile
+++ b/justfile
@@ -1,4 +1,3 @@
-packpath := justfile_directory() / "packpath"
 scripts := justfile_directory() / "scripts"
 doc := justfile_directory() / "doc"
 devcontainer := justfile_directory() / ".devcontainer/lazyvim/Dockerfile"
@@ -10,15 +9,18 @@ demos := justfile_directory() / "demos"
 
 init_lua := scripts / "minimal_init.lua"
 
+export LEAN_NVIM_ISOLATED_CONFIG_ROOT := justfile_directory() / ".isolated_config_for_tests"
+packpath := LEAN_NVIM_ISOLATED_CONFIG_ROOT / "local/share/nvim/site/pack/testing/start"
+
 # Run the lean.nvim test suite.
 [group('testing')]
-test: _rebuild-test-fixtures _clone-test-dependencies
+test: _rebuild-test-fixtures
     @just retest
 
 # Run the test suite without rebuilding or recloning any dependencies.
 [group('testing')]
 retest *test_files=spec:
-    nvim --headless --clean -u {{ init_lua }} -c 'lua require("inanis").run{ specs = vim.split("{{ test_files }}", " "), minimal_init = "{{ init_lua }}", sequential = vim.env.TEST_SEQUENTIAL ~= nil }'
+    eval $(luarocks path --no-bin --lua-version 5.1); luarocks --lua-version 5.1 test --local -- {{ test_files }}
 
 # Run an instance of neovim with the same minimal init used to run tests.
 [group('dev')]
@@ -39,7 +41,7 @@ scratch *ARGS='':
 
 # Coarsely profile how long the whole test suite takes to run.
 [group('testing')]
-profile-test *ARGS: _rebuild-test-fixtures _clone-test-dependencies
+profile-test *ARGS: _rebuild-test-fixtures
     hyperfine --warmup 2 {{ ARGS }} "just retest"
 
 # Lint lean.nvim for style and typing issues.
@@ -49,7 +51,7 @@ lint:
     {{ if `lua-language-server --version 2>&1 >/dev/null; echo $?` != "0" { error('lua-language-server not found') } else { "" } }}
     lua-language-server --check {{ lean }} --checklevel=Warning --configpath "{{ justfile_directory() }}/.luarc.json"
     {{ if `selene --version 2>&1 >/dev/null; echo $?` != "0" { error('selene not found') } else { "" } }}
-    selene {{ src }}
+    selene {{ src }} {{ spec }}
 
 # Rebuild a demo from our VHS script.
 demo:
@@ -85,19 +87,13 @@ bump-test-fixtures:
 
 # Delete any previously cloned dependencies.
 _clean-dependencies:
-    rm -rf '{{ packpath }}'
-    mkdir '{{ packpath }}'
+    rm -rf '{{ LEAN_NVIM_ISOLATED_CONFIG_ROOT }}'
 
 # Clone any neovim dependencies required for the plugin.
 _clone-dependencies: _clean-dependencies
+    mkdir -p '{{ packpath }}'
     for dependency in AndrewRadev/switch.vim andymass/vim-matchup neovim/nvim-lspconfig nvim-lua/plenary.nvim tomtom/tcomment_vim lewis6991/satellite.nvim; do \
-        git clone --quiet --filter=blob:none "https://github.com/$dependency" "{{ packpath }}/$(basename $dependency)"; \
-    done
-
-# Clone any neovim dependencies required for the test suite.
-_clone-test-dependencies: _clone-dependencies
-    for dependency in Julian/inanis.nvim; do \
-        git clone --quiet --filter=blob:none "https://github.com/$dependency" "{{ packpath }}/$(basename $dependency)"; \
+      git clone --quiet --filter=blob:none "https://github.com/$dependency" "{{ packpath }}/$(basename $dependency)"; \
     done
 
 # Rebuild some test fixtures used in the test suite.
diff --git a/lean.nvim-scm-1.rockspec b/lean.nvim-scm-1.rockspec
index 4aa586ab..902bf028 100644
--- a/lean.nvim-scm-1.rockspec
+++ b/lean.nvim-scm-1.rockspec
@@ -16,6 +16,8 @@ dependencies = {
   'nvim-lspconfig',
   'plenary.nvim',
 }
+test_dependencies = {
+}
 
 source = {
   url = 'https://github.com/Julian/lean.nvim',
diff --git a/spec/fixtures.lua b/spec/fixtures.lua
index 5532f7cf..fd1f72bb 100644
--- a/spec/fixtures.lua
+++ b/spec/fixtures.lua
@@ -1,3 +1,5 @@
+local assert = require 'luassert.assert'
+
 local this_file = debug.getinfo(1).source:match '@(.*)$'
 
 local root = vim.fs.joinpath(vim.fs.dirname(this_file), 'fixtures')
diff --git a/spec/nvim-shim b/spec/nvim-shim
new file mode 100755
index 00000000..55300d09
--- /dev/null
+++ b/spec/nvim-shim
@@ -0,0 +1,8 @@
+#!/bin/sh
+set -euf -o pipefail
+
+export XDG_CONFIG_HOME="$LEAN_NVIM_ISOLATED_CONFIG_ROOT/config"
+export XDG_STATE_HOME="$LEAN_NVIM_ISOLATED_CONFIG_ROOT/local/state/"
+export XDG_DATA_HOME="$LEAN_NVIM_ISOLATED_CONFIG_ROOT/local/share/"
+
+nvim -l $@
diff --git a/spec/spec_helper.lua b/spec/spec_helper.lua
new file mode 100644
index 00000000..646cf409
--- /dev/null
+++ b/spec/spec_helper.lua
@@ -0,0 +1,25 @@
+local assert = require 'luassert.assert'
+local say = require 'say'
+
+--- Assert a Lua object is empty.
+--- In particular, the empty string, empty table and nil are all empty.
+local function is_empty(_, arguments)
+  local got = arguments[1]
+  if not got then
+    return true
+  elseif type(got) == 'string' then
+    return got == ''
+  else
+    return vim.tbl_isempty(got)
+  end
+end
+
+say:set('assertion.empty.positive', '%q is non-empty')
+say:set('assertion.empty.negative', '%q is empty')
+assert:register(
+  'assertion',
+  'empty',
+  is_empty,
+  'assertion.empty.positive',
+  'assertion.empty.negative'
+)