rspec WIP

Working

Refactor: scaffold branch popup spec, extract shared contexts

Add ruby tests to GHA

Add linux to bundle gemlock for CI

Don't get deps in CI

Needs the project

Packadd deps

Refactoring test setup

Add back cwd to rtp

debug

empty

Use runner temp dir

debug

Try new name

Needs trailing slash

Skip this for now

Give up

Add the minimal init stuff

no

try this

try THIS

Pass env here

test

rel path

not clean in ci

closer

init repo first?

More branch spec

empty

logging

wait more

test

test

Put back

update gitignore

Add debug and run on macos

Disconnect

bin path

bin

Something

chmod bin

try bin

Use macos bin

Debugging
This commit is contained in:
Cameron 2023-12-19 09:18:30 +01:00
parent 3469de181d
commit 6f54a04b9d
No known key found for this signature in database
GPG key ID: 7998CB3EA6CE5CBC
16 changed files with 507 additions and 31 deletions

View file

@ -13,28 +13,41 @@ jobs:
strategy:
matrix:
release: [stable, nightly]
env:
CI: "1"
steps:
- uses: actions/checkout@v4
- name: Install Dependencies
run: |
mkdir -p ~/.local/share/neogit-test/site/pack/plenary.nvim/start
cd ~/.local/share/neogit-test/site/pack/plenary.nvim/start
git clone https://github.com/nvim-lua/plenary.nvim
mkdir -p ~/.local/share/neogit-test/site/pack/telescope.nvim/start
cd ~/.local/share/neogit-test/site/pack/telescope.nvim/start
git clone https://github.com/nvim-telescope/telescope.nvim
- name: Install Neovim
run: |
wget https://github.com/neovim/neovim/releases/download/${{ matrix.release }}/nvim-linux64.tar.gz
tar -zxf nvim-linux64.tar.gz
sudo ln -s $(pwd)/nvim-linux64/bin/nvim /usr/local/bin
- name: Test
continue-on-error: false
env:
ci: "1"
- name: Install Dependencies
run: |
make test
mkdir -p ~/.local/share/nvim/site/pack/
cd ~/.local/share/nvim/site/pack/
mkdir -p ./plenary.nvim/start
cd ./plenary.nvim/start
git clone https://github.com/nvim-lua/plenary.nvim
mkdir -p ./telescope.nvim/start
cd ./telescope.nvim/start
git clone https://github.com/nvim-telescope/telescope.nvim
# - name: Luassert Test
# continue-on-error: true
# run: |
# make test
- uses: ruby/setup-ruby@v1
with:
bundler-cache: true
- name: E2E Test
env:
NVIM_RUBY_LOG_LEVEL: "debug"
run: |
bundle exec rspec

1
.gitignore vendored
View file

@ -6,3 +6,4 @@ doc/tags
# Environment
.envrc
/tests/.min/*

1
.ruby-version Normal file
View file

@ -0,0 +1 @@
3.3.0

15
Gemfile Normal file
View file

@ -0,0 +1,15 @@
# frozen_string_literal: true
ruby File.read(".ruby-version").strip
source "https://rubygems.org"
gem "debug"
gem "fuubar"
gem "neovim"
gem "quickfix_formatter"
gem "rspec"
gem "tmpdir"
gem "git"
gem "super_diff"
gem "activesupport"

106
Gemfile.lock Normal file
View file

@ -0,0 +1,106 @@
GEM
remote: https://rubygems.org/
specs:
activesupport (7.1.2)
base64
bigdecimal
concurrent-ruby (~> 1.0, >= 1.0.2)
connection_pool (>= 2.2.5)
drb
i18n (>= 1.6, < 2)
minitest (>= 5.1)
mutex_m
tzinfo (~> 2.0)
addressable (2.8.6)
public_suffix (>= 2.0.2, < 6.0)
attr_extras (7.1.0)
base64 (0.2.0)
bigdecimal (3.1.5)
concurrent-ruby (1.2.2)
connection_pool (2.4.1)
debug (1.9.1)
irb (~> 1.10)
reline (>= 0.3.8)
diff-lcs (1.5.0)
drb (2.2.0)
ruby2_keywords
fileutils (1.7.2)
fuubar (2.5.1)
rspec-core (~> 3.0)
ruby-progressbar (~> 1.4)
git (1.19.0)
addressable (~> 2.8)
rchardet (~> 1.8)
i18n (1.14.1)
concurrent-ruby (~> 1.0)
io-console (0.7.1)
irb (1.11.0)
rdoc
reline (>= 0.3.8)
minitest (5.20.0)
msgpack (1.7.2)
multi_json (1.15.0)
mutex_m (0.2.0)
neovim (0.9.1)
msgpack (~> 1.1)
multi_json (~> 1.0)
optimist (3.1.0)
patience_diff (1.2.0)
optimist (~> 3.0)
psych (5.1.2)
stringio
public_suffix (5.0.4)
quickfix_formatter (0.1.0)
rspec (>= 3.12.0)
rchardet (1.8.0)
rdoc (6.6.2)
psych (>= 4.0.0)
reline (0.4.1)
io-console (~> 0.5)
rspec (3.12.0)
rspec-core (~> 3.12.0)
rspec-expectations (~> 3.12.0)
rspec-mocks (~> 3.12.0)
rspec-core (3.12.2)
rspec-support (~> 3.12.0)
rspec-expectations (3.12.3)
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.12.0)
rspec-mocks (3.12.6)
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.12.0)
rspec-support (3.12.1)
ruby-progressbar (1.13.0)
ruby2_keywords (0.0.5)
stringio (3.1.0)
super_diff (0.10.0)
attr_extras (>= 6.2.4)
diff-lcs
patience_diff
tmpdir (0.2.0)
fileutils
tzinfo (2.0.6)
concurrent-ruby (~> 1.0)
PLATFORMS
arm64-darwin-22
arm64-darwin-23
x86_64-darwin-20
x86_64-linux
DEPENDENCIES
activesupport
debug
fuubar
git
neovim
quickfix_formatter
rspec
super_diff
tmpdir
RUBY VERSION
ruby 3.3.0p0
BUNDLED WITH
2.4.21

View file

@ -1,5 +1,5 @@
test:
LUA_PATH="./?.lua" TEST_FILES=$$TEST_FILES NEOGIT_LOG_LEVEL=error NEOGIT_LOG_CONSOLE="sync" GIT_CONFIG_GLOBAL=/dev/null GIT_CONFIG_SYSTEM=/dev/null NVIM_APPNAME=neogit-test nvim --headless -S "./tests/init.lua"
TEMP_DIR=$$TEMP_DIR TEST_FILES=$$TEST_FILES NEOGIT_LOG_LEVEL=error NEOGIT_LOG_CONSOLE="sync" GIT_CONFIG_GLOBAL=/dev/null GIT_CONFIG_SYSTEM=/dev/null NVIM_APPNAME=neogit-test nvim --headless -S "./tests/init.lua"
lint:
selene --config selene/config.toml lua

View file

@ -0,0 +1,125 @@
# frozen_string_literal: true
require "spec_helper"
RSpec.describe "Branch Popup", :git, :nvim do
describe "Variables" do
describe "branch.<current>.description" do
it "can edit branch description"
end
describe "branch.<current>.{merge,remote}" do
it "can set the upstream for current branch"
end
describe "branch.<current>.rebase" do
it "can change rebase setting"
end
describe "branch.<current>.pushRemote" do
it "can change pushRemote for current branch"
end
end
describe "Actions" do
describe "Checkout branch/revision" do
it "can checkout a local branch"
it "can checkout a remote branch"
it "can checkout a tag"
it "can checkout HEAD"
it "can checkout a commit"
end
describe "Checkout local branch" do
before { git.branch("new-local-branch").checkout }
it "can checkout a local branch" do
nvim.feedkeys("bl")
nvim.feedkeys("master<cr>")
expect(git.current_branch).to eq "master"
end
it "creates and checks out a new local branch when choosing a remote"
end
describe "Checkout recent branch" do
it "can checkout a local branch"
end
describe "Checkout new branch" do
it "can create and checkout a branch" do
nvim.input("new-branch")
nvim.feedkeys("bc")
nvim.feedkeys("master<cr>")
expect(git.current_branch).to eq "new-branch"
end
it "replaces spaces with dashes in user input" do
nvim.input("new branch with spaces")
nvim.feedkeys("bc")
nvim.feedkeys("master<cr>")
expect(git.current_branch).to eq "new-branch-with-spaces"
end
it "lets you pick a base branch" do
git.branch("new-base-branch").checkout
nvim.input("feature-branch")
nvim.feedkeys("bc")
nvim.feedkeys("master<cr>")
expect(git.current_branch).to eq "feature-branch"
expect(
git.merge_base("feature-branch", "master").first.sha
).to eq(git.revparse("master"))
end
end
end
describe "Checkout new spin-off" do
it "can create and checkout a spin-off branch"
end
describe "Checkout new worktree" do
it "can create and checkout a worktree"
end
describe "Create new branch" do
it "can create a new branch"
end
describe "Create new spin-off" do
it "can create a new spin-off"
context "when there are uncommitted changes" do
it "checks out the spun-off branch"
end
end
describe "Create new worktree" do
it "can create a new worktree"
end
describe "Configure" do
it "Launches the configuration popup"
end
describe "Rename" do
it "can rename a branch"
end
describe "reset" do
it "can reset a branch"
end
describe "delete" do
it "can delete a branch"
end
describe "pull request" do
# Requires Neovim 0.10
end
end

61
spec/spec_helper.rb Normal file
View file

@ -0,0 +1,61 @@
# frozen_string_literal: true
require "tmpdir"
require "git"
require "neovim"
require "debug"
require "active_support/all"
PROJECT_DIR = File.expand_path(File.join(__dir__, ".."))
Dir[File.join(File.expand_path("."), "spec", "support", "**", "*.rb")].each { |f| require f }
# Thread.new do
# loop do
# sleep 10 # seconds
# puts "=" * 80;
# Thread.list.each.with_index { |t, i| puts "== Thread #{i}"; puts t.backtrace }
# end
# end
# module Neovim
# class Connection
# def self.child(argv)
# argv = argv.include?("--embed") ? argv : argv + ["--embed"]
#
# io = ::IO.popen(argv, "rb+")
# # Process.detach(io.pid)
#
# new(io, io)
# end
# end
# end
RSpec.configure do |config|
config.expect_with :rspec do |expectations|
expectations.include_chain_clauses_in_custom_matcher_descriptions = true
end
config.mock_with :rspec do |mocks|
mocks.verify_partial_doubles = true
end
config.shared_context_metadata_behavior = :apply_to_host_groups
config.filter_run_when_matching :focus
config.example_status_persistence_file_path = "spec/examples.txt"
config.disable_monkey_patching!
config.warnings = true
config.profile_examples = 10
config.order = :random
config.include Helpers
config.around(:each) do |example|
Dir.mktmpdir do |tmp|
Dir.chdir(tmp) do
Git.init
example.run
end
end
end
end

View file

@ -0,0 +1,14 @@
# frozen_string_literal: true
RSpec.shared_context "git", :git do
let(:git) { Git.open(Dir.pwd) }
before do
system("touch testfile")
git.config("user.email", "test@example.com")
git.config("user.name", "tester")
git.add("testfile")
git.commit("Initial commit")
end
end

View file

@ -0,0 +1,8 @@
# frozen_string_literal: true
RSpec.shared_context "nvim", :nvim do
let(:nvim) { NeovimClient.new }
before { nvim.setup }
after { nvim.teardown }
end

View file

@ -0,0 +1,23 @@
# frozen_string_literal: true
return if ENV["CI"]
def dir_name(name)
name.match(/[^\/]+\/(?<dir_name>[^\.]+)/)[:dir_name]
end
def ensure_installed(name)
tmp = File.join(PROJECT_DIR, "tmp")
Dir.mkdir(tmp) if !Dir.exist?(tmp)
dir = File.join(tmp, dir_name(name))
return if Dir.exist?(dir) && !Dir.empty?(dir)
puts "Downloading dependency #{name} to #{dir}"
Dir.mkdir(dir)
Git.clone("git@github.com:#{name}.git", dir)
end
ensure_installed "nvim-lua/plenary.nvim"
ensure_installed "nvim-telescope/telescope.nvim"

21
spec/support/helpers.rb Normal file
View file

@ -0,0 +1,21 @@
# frozen_string_literal: true
module Helpers
# def wait_for_expect
# last_error = nil
# success = false
#
# 5.times do
# begin
# yield
# success = true
# break
# rescue RSpec::Expectations::ExpectationNotMetError => e
# last_error = e
# sleep 0.5
# end
# end
#
# raise last_error if !success && last_error
# end
end

0
spec/support/init.lua Normal file
View file

View file

@ -0,0 +1,82 @@
# frozen_string_literal: true
class NeovimClient
def initialize
@instance = nil
end
def setup
@instance = attach_child
if ENV["CI"]
lua <<~LUA
vim.cmd.runtime("plugin/plenary.vim")
vim.cmd.runtime("plugin/neogit.lua")
LUA
else
# Sets up the runtimepath
runtime_dependencies.each do |dep|
lua "vim.opt.runtimepath:prepend('#{dep}')"
end
end
lua "vim.opt.runtimepath:prepend('#{PROJECT_DIR}')"
lua <<~LUA
require("plenary")
require('neogit').setup()
require('neogit').open()
LUA
sleep(0.025) # Seems to be about right
end
def teardown
@instance.shutdown
@instance = nil
end
def print_screen
puts get_lines
end
def lua(code)
@instance.exec_lua(code, [])
end
def get_lines
@instance.current.buffer.get_lines(0, -1, true).join("\n")
end
# Overload vim.fn.input() to prevent blocking.
def input(*args)
lua <<~LUA
local inputs = { #{args.map(&:inspect).join(",")} }
vim.fn.input = function()
return table.remove(inputs, 1)
end
LUA
end
# Higher-level user input
def feedkeys(keys, mode: 'm')
@instance.feedkeys(
@instance.replace_termcodes(keys, true, false, true),
mode,
false
)
end
def attach_child
if ENV["CI"]
Neovim.attach_child(["nvim", "--embed", "--headless"])
else
Neovim.attach_child(["nvim", "--embed", "--clean", "--headless"])
end
end
def runtime_dependencies
Dir[File.join(PROJECT_DIR, "tmp", "*")].select { Dir.exist? _1 }
end
end

View file

@ -1,25 +1,11 @@
local util = require("tests.util.util")
local function ensure_installed(repo)
local name = repo:match(".+/(.+)$")
local install_path = util.neogit_test_base_dir .. name
vim.opt.runtimepath:prepend(install_path)
if not vim.loop.fs_stat(install_path) then
print("* Downloading " .. name .. " to '" .. install_path .. "/'")
vim.fn.system { "git", "clone", "--depth=1", "git@github.com:" .. repo .. ".git", install_path }
end
end
if os.getenv("CI") then
vim.opt.runtimepath:prepend(vim.fn.getcwd())
vim.cmd([[runtime! plugin/plenary.vim]])
vim.cmd([[runtime! plugin/neogit.lua]])
else
ensure_installed("nvim-lua/plenary.nvim")
ensure_installed("nvim-telescope/telescope.nvim")
util.ensure_installed("nvim-lua/plenary.nvim", util.neogit_test_base_dir)
end
require("plenary.test_harness").test_directory(

View file

@ -48,4 +48,24 @@ function M.create_temp_dir(suffix)
return prefix .. vim.trim(M.system(cmd))
end
function M.ensure_installed(repo, path)
local name = repo:match(".+/(.+)$")
local install_path = path .. name
vim.opt.runtimepath:prepend(install_path)
if not vim.loop.fs_stat(install_path) then
print("* Downloading " .. name .. " to '" .. install_path .. "/'")
vim.fn.system { "git", "clone", "--depth=1", "git@github.com:" .. repo .. ".git", install_path }
if vim.v.shell_error > 0 then
error(string.format("! Failed to clone plugin: '%s' in '%s'!", name, install_path),
vim.log.levels.ERROR)
end
end
print(vim.fn.system("ls " ..install_path))
end
return M