chore: setup

This commit is contained in:
Chen Asraf
2023-05-15 02:09:42 +03:00
commit 45f1acb86f
28 changed files with 1080 additions and 0 deletions

9
.editorconfig Normal file
View File

@@ -0,0 +1,9 @@
[*]
tab_width = 2
indent_size = 2
indent_style = space
insert_final_newline = true
trim_trailing_whitespace = true
[*.md]
trim_trailing_whitespace = false

2
.eslintignore Normal file
View File

@@ -0,0 +1,2 @@
templates/
scaffolds/

1
.github/CODEOWNERS vendored Normal file
View File

@@ -0,0 +1 @@
* @chenasraf

24
.github/ISSUE_TEMPLATE/Bug_report.md vendored Normal file
View File

@@ -0,0 +1,24 @@
---
name: Bug report
about: It helps making the plugin more stable.
---
## Description
<!-- A clear and concise description of what the bug is. -->
## Steps to reproduce
1. I did the command `...`
2. Then I saw `...`
3. Error
## Expected behavior
<!-- A clear and concise description of what you expected to happen. -->
## Environment
- Neovim version: [e.g. 0.5.x / 0.6.x / 0.7.x / 0.8.x / Nightly]
- text-transform version: [e.g. latest / 0.1.2 / dev]
- Plugin clash: [e.g. Telescope float window / lsp diagnostic]

View File

@@ -0,0 +1,13 @@
---
name: Feature request
about: Suggest anything that would make your life easier, or the plugin better.
---
## Describe the problem
<!-- Explain what the new feature is, or if it's for the documentation, what do you expect. -->
## Describe the solution
<!-- Explain what your solution would look like. -->

7
.github/PULL_REQUEST_TEMPLATE.md vendored Normal file
View File

@@ -0,0 +1,7 @@
## 📃 Summary
<!-- Provide some context about the pull request, it makes the review easier. -->
## 📸 Preview
<!-- If there's a visual impact to your change, please provide a screenshot. You can directly upload it to GitHub by dragging in this text area. -->

102
.github/workflows/main.yml vendored Normal file
View File

@@ -0,0 +1,102 @@
name: Release
on:
push:
branches: [master]
pull_request:
types: [opened, synchronize]
concurrency:
group: github.head_ref
cancel-in-progress: true
jobs:
lint:
runs-on: ubuntu-latest
name: lint
steps:
- uses: actions/checkout@v3
- uses: JohnnyMorganz/stylua-action@v2
with:
token: ${{ secrets.GITHUB_TOKEN }}
version: latest
args: --check .
documentation:
runs-on: ubuntu-latest
name: documentation
steps:
- uses: actions/checkout@v3
with:
fetch-depth: 2
- name: setup neovim
uses: rhysd/action-setup-vim@v1
with:
neovim: true
version: v0.8.3
- name: generate documentation
run: make documentation-ci
- name: check docs diff
run: exit $(git status --porcelain doc | wc -l | tr -d " ")
# tests:
# needs:
# - lint
# - documentation
# runs-on: ubuntu-latest
# timeout-minutes: 2
# strategy:
# matrix:
# neovim_version: ['v0.7.2', 'v0.8.3', 'v0.9.0', 'nightly']
# steps:
# - uses: actions/checkout@v3
# - run: date +%F > todays-date
# - name: restore cache for today's nightly.
# uses: actions/cache@v3
# with:
# path: _neovim
# key: ${{ runner.os }}-x64-${{ hashFiles('todays-date') }}
# - name: setup neovim
# uses: rhysd/action-setup-vim@v1
# with:
# neovim: true
# version: ${{ matrix.neovim_version }}
# - name: run tests
# run: make test-ci
release:
name: release
if: ${{ github.ref == 'refs/heads/master' }}
permissions: write-all
needs:
- lint
- documentation
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v3
- uses: google-github-actions/release-please-action@v3
id: release
with:
release-type: simple
package-name: text-transform.nvim
- name: tag stable versions
if: ${{ steps.release.outputs.release_created }}
run: |
git config user.name github-actions[bot]
git config user.email github-actions[bot]@users.noreply.github.com
git remote add gh-token "https://${{ secrets.GITHUB_TOKEN }}@github.com/google-github-actions/release-please-action.git"
git tag -d stable || true
git push origin :stable || true
git tag -a stable -m "Last Stable Release"
git push origin stable

3
.gitignore vendored Normal file
View File

@@ -0,0 +1,3 @@
deps
**.DS_Store
.luarc.json

2
.prettierignore Normal file
View File

@@ -0,0 +1,2 @@
templates/
scaffolds/

15
.prettierrc Normal file
View File

@@ -0,0 +1,15 @@
{
"printWidth": 100,
"semi": false,
"singleQuote": true,
"trailingComma": "all",
"overrides": [
{
"files": "*.md",
"options": {
"printWidth": 100,
"proseWrap": "always"
}
}
]
}

2
.styluaignore Normal file
View File

@@ -0,0 +1,2 @@
deps/
**/mini/

2
CHANGELOG.md Normal file
View File

@@ -0,0 +1,2 @@
# Changelog

12
FUNDING.yml Normal file
View File

@@ -0,0 +1,12 @@
# These are supported funding model platforms
github: chenasraf
patreon: # Replace with a single Patreon username
open_collective: # Replace with a single Open Collective username
ko_fi: casraf
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry
liberapay: # Replace with a single Liberapay username
issuehunt: # Replace with a single IssueHunt username
otechie: # Replace with a single Otechie username
custom: ["https://www.paypal.com/cgi-bin/webscr?cmd=_donations&business=TSH3C3ABGQM22&currency_code=ILS&source=url"]

21
LICENSE Normal file
View File

@@ -0,0 +1,21 @@
MIT License
Copyright (c) 2023 Chen Asraf
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

34
Makefile Normal file
View File

@@ -0,0 +1,34 @@
# we disable the `all` command because some external tool might run it automatically
.SUFFIXES:
all:
# runs all the test files.
test:
nvim --version | head -n 1 && echo ''
nvim --headless --noplugin -u ./scripts/minimal_init.lua \
-c "lua require('mini.test').setup()" \
-c "lua MiniTest.run({ execute = { reporter = MiniTest.gen_reporter.stdout({ group_depth = 1 }) } })"
# installs `mini.nvim`, used for both the tests and documentation.
deps:
@mkdir -p deps
git clone --depth 1 https://github.com/echasnovski/mini.nvim deps/mini.nvim
# installs deps before running tests, useful for the CI.
test-ci: deps test
# generates the documentation.
documentation:
nvim --headless --noplugin -u ./scripts/minimal_init.lua -c "lua require('mini.doc').generate()" -c "qa!"
# installs deps before running the documentation generation, useful for the CI.
documentation-ci: deps documentation
# performs a lint check and fixes issue if possible, following the config in `stylua.toml`.
lint:
stylua .
# setup
setup:
./scripts/setup.sh

132
README.md Normal file
View File

@@ -0,0 +1,132 @@
<p align="center">
<h1 align="center">text-transform.nvim</h2>
</p>
<p align="center">
> A catch phrase that describes your plugin.
</p>
<div align="center">
> Drag your video (<10MB) here to host it for free on GitHub.
</div>
<div align="center">
> Videos don't work on GitHub mobile, so a GIF alternative can help users.
_[GIF version of the showcase video for mobile users](SHOWCASE_GIF_LINK)_
</div>
## ⚡️ Features
> Write short sentences describing your plugin features
- FEATURE 1
- FEATURE ..
- FEATURE N
## 📋 Installation
<div align="center">
<table>
<thead>
<tr>
<th>Package manager</th>
<th>Snippet</th>
</tr>
</thead>
<tbody>
<tr>
<td>
[wbthomason/packer.nvim](https://github.com/wbthomason/packer.nvim)
</td>
<td>
```lua
-- stable version
use {"text-transform.nvim", tag = "*" }
-- dev version
use {"text-transform.nvim"}
```
</td>
</tr>
<tr>
<td>
[junegunn/vim-plug](https://github.com/junegunn/vim-plug)
</td>
<td>
```lua
-- stable version
Plug "text-transform.nvim", { "tag": "*" }
-- dev version
Plug "text-transform.nvim"
```
</td>
</tr>
<tr>
<td>
[folke/lazy.nvim](https://github.com/folke/lazy.nvim)
</td>
<td>
```lua
-- stable version
require("lazy").setup({{"text-transform.nvim", version = "*"}})
-- dev version
require("lazy").setup({"text-transform.nvim"})
```
</td>
</tr>
</tbody>
</table>
</div>
## ☄ Getting started
> Describe how to use the plugin the simplest way
## ⚙ Configuration
> The configuration list sometimes become cumbersome, making it folded by default reduce the noise of the README file.
<details>
<summary>Click to unfold the full list of options with their default values</summary>
> **Note**: The options are also available in Neovim by calling `:h text-transform.options`
```lua
require("text-transform").setup({
-- you can copy the full list from lua/text-transform/config.lua
})
```
</details>
## 🧰 Commands
| Command | Description |
|-------------|----------------------------|
| `:Toggle` | Enables the plugin. |
## ⌨ Contributing
PRs and issues are always welcome. Make sure to provide as much context as possible when opening one.
## 🗞 Wiki
You can find guides and showcase of the plugin on [the Wiki](https://github.com/chenasraf/text-transform.nvim/wiki)
## 🎭 Motivations
> If alternatives of your plugin exist, you can provide some pros/cons of using yours over the others.

2
doc/tags Normal file
View File

@@ -0,0 +1,2 @@
TextTransform.options text-transform.txt /*TextTransform.options*
TextTransform.setup() text-transform.txt /*TextTransform.setup()*

31
doc/text-transform.txt Normal file
View File

@@ -0,0 +1,31 @@
==============================================================================
------------------------------------------------------------------------------
*TextTransform.options*
`TextTransform.options`
Your plugin configuration with its default values.
Default values:
>
TextTransform.options = {
-- Prints useful logs about what event are triggered, and reasons actions are executed.
debug = false,
keymap = {
"<Leader>~",
},
}
<
------------------------------------------------------------------------------
*TextTransform.setup()*
`TextTransform.setup`({options})
Define your text-transform setup.
Parameters~
{options} `(table)` Module config table. See |TextTransform.options|.
Usage~
`require("text-transform").setup()` (add `{}` with your |TextTransform.options| table)
vim:tw=78:ts=8:noet:ft=help:norl:

View File

@@ -0,0 +1,28 @@
local TextTransform = {}
--- Your plugin configuration with its default values.
---
--- Default values:
---@eval return MiniDoc.afterlines_to_code(MiniDoc.current.eval_section)
TextTransform.options = {
-- Prints useful logs about what event are triggered, and reasons actions are executed.
debug = false,
keymap = {
"<Leader>~",
},
}
--- Define your text-transform setup.
---
---@param options table Module config table. See |TextTransform.options|.
---
---@usage `require("text-transform").setup()` (add `{}` with your |TextTransform.options| table)
function TextTransform.setup(options)
options = options or {}
TextTransform.options = vim.tbl_deep_extend("keep", options, TextTransform.options)
return TextTransform.options
end
return TextTransform

View File

@@ -0,0 +1,41 @@
local M = require("text-transform.main")
local TextTransform = {}
-- Toggle the plugin by calling the `enable`/`disable` methods respectively.
function TextTransform.toggle()
-- when the config is not set to the global object, we set it
if _G.TextTransform.config == nil then
_G.TextTransform.config = require("text-transform.config").options
end
_G.TextTransform.state = M.toggle()
end
-- starts TextTransform and set internal functions and state.
function TextTransform.enable()
if _G.TextTransform.config == nil then
_G.TextTransform.config = require("text-transform.config").options
end
local state = M.enable()
if state ~= nil then
_G.TextTransform.state = state
end
return state
end
-- disables TextTransform and reset internal functions and state.
function TextTransform.disable()
_G.TextTransform.state = M.disable()
end
-- setup TextTransform options and merge them with user provided ones.
function TextTransform.setup(opts)
_G.TextTransform.config = require("text-transform.config").setup(opts)
end
_G.TextTransform = TextTransform
return _G.TextTransform

View File

@@ -0,0 +1,49 @@
local D = require("text-transform.util.debug")
-- internal methods
local TextTransform = {}
-- state
local S = {
-- Boolean determining if the plugin is enabled or not.
enabled = false,
}
---Toggle the plugin by calling the `enable`/`disable` methods respectively.
---@private
function TextTransform.toggle()
if S.enabled then
return TextTransform.disable()
end
return TextTransform.enable()
end
---Initializes the plugin.
---@private
function TextTransform.enable()
if S.enabled then
return S
end
S.enabled = true
return S
end
---Disables the plugin and reset the internal state.
---@private
function TextTransform.disable()
if not S.enabled then
return S
end
-- reset the state
S = {
enabled = false,
}
return S
end
return TextTransform

View File

@@ -0,0 +1,61 @@
local D = {}
---prints only if debug is true.
---
---@param scope string: the scope from where this function is called.
---@param str string: the formatted string.
---@param ... any: the arguments of the formatted string.
---@private
function D.log(scope, str, ...)
if _G.TextTransform.config ~= nil and not _G.TextTransform.config.debug then
return
end
local info = debug.getinfo(2, "Sl")
local line = ""
if info then
line = "L" .. info.currentline
end
print(
string.format(
"[text-transform:%s %s in %s] > %s",
os.date("%H:%M:%S"),
line,
scope,
string.format(str, ...)
)
)
end
---prints the table if debug is true.
---
---@param table table: the table to print.
---@param indent number?: the default indent value, starts at 0.
---@private
function D.tprint(table, indent)
if _G.TextTransform.config ~= nil and not _G.TextTransform.config.debug then
return
end
if not indent then
indent = 0
end
for k, v in pairs(table) do
local formatting = string.rep(" ", indent) .. k .. ": "
if type(v) == "table" then
print(formatting)
D.tprint(v, indent + 1)
elseif type(v) == "boolean" then
print(formatting .. tostring(v))
elseif type(v) == "function" then
print(formatting .. "FUNCTION")
else
print(formatting .. v)
end
end
end
return D

164
plugin/text-transform.lua Normal file
View File

@@ -0,0 +1,164 @@
-- You can use this loaded variable to enable conditional parts of your plugin.
if _G.TextTransformLoaded then
return
end
_G.TextTransformLoaded = true
local function into_words(str)
local words = {}
local word = ""
local previous_is_upper = false
for i = 1, #str do
local char = str:sub(i, i)
-- split on uppercase letters
if char:match("%u") and not previous_is_upper then
if word ~= "" then
table.insert(words, word)
end
previous_is_upper = true
word = char
-- split on underscores, hyphens, and spaces
elseif char:match("[%_%-%s]") then
if word ~= "" then
table.insert(words, word)
previous_is_upper = false
end
word = ""
else
word = word .. char
previous_is_upper = char:match("%u")
end
end
if word ~= "" then
table.insert(words, word)
previous_is_upper = false
end
return words
end
function IntoWords(string)
print(vim.inspect(into_words(string)))
end
function CamelCase(string)
local words = into_words(string)
local camel_case = ""
for i, word in ipairs(words) do
if i == 1 then
camel_case = camel_case .. word:lower()
else
camel_case = camel_case .. word:sub(1, 1):upper() .. word:sub(2):lower()
end
end
return camel_case
end
function SnakeCase(string)
local words = into_words(string)
local snake_case = ""
for i, word in ipairs(words) do
if i == 1 then
snake_case = snake_case .. word:lower()
else
snake_case = snake_case .. "_" .. word:lower()
end
end
return snake_case
end
function PascalCase(string)
local words = into_words(string)
local pascal_case = ""
for _, word in ipairs(words) do
pascal_case = pascal_case .. word:sub(1, 1):upper() .. word:sub(2):lower()
end
return pascal_case
end
function KebabCase(string)
local words = into_words(string)
local kebab_case = ""
for i, word in ipairs(words) do
if i == 1 then
kebab_case = kebab_case .. word:lower()
else
kebab_case = kebab_case .. "-" .. word:lower()
end
end
return kebab_case
end
function DotCase(string)
local words = into_words(string)
local dot_case = ""
for i, word in ipairs(words) do
if i == 1 then
dot_case = dot_case .. word:lower()
else
dot_case = dot_case .. "." .. word:lower()
end
end
return dot_case
end
function TitleCase(string)
local words = into_words(string)
local title_case = ""
for i, word in ipairs(words) do
title_case = title_case .. word:sub(1, 1):upper() .. word:sub(2):lower()
if i ~= #words then
title_case = title_case .. " "
end
end
return title_case
end
function ReplaceCurrentSelection(transform)
local selection = vim.fn.getline("'<", "'>")
local transformed = transform(selection)
vim.fn.setline("'<", transformed)
end
function ReplaceCurrentWord(transform)
local word = vim.fn.expand("<cword>")
local transformed = transform(word)
vim.cmd("normal ciw" .. transformed)
end
local should_test = false
if should_test then
local map = {
["CamelCase"] = CamelCase,
["SnakeCase"] = SnakeCase,
["PascalCase"] = PascalCase,
["KebabCase"] = KebabCase,
["DotCase"] = DotCase,
["TitleCase"] = TitleCase,
}
for k, tst in pairs(map) do
print(k .. ": " .. "hello_world" .. " => " .. tst("hello_world"))
print(k .. ": " .. "HELLO_WORLD" .. " => " .. tst("HELLO_WORLD"))
print(k .. ": " .. "HelloWorld" .. " => " .. tst("HelloWorld"))
print(k .. ": " .. "Hello-World" .. " => " .. tst("Hello-World"))
end
end
-- use input from current word in editor
vim.cmd("amenu Transforms.&camelCase :lua ReplaceCurrentWord(CamelCase)<CR>")
vim.cmd("amenu Transforms.&snake_case :lua ReplaceCurrentWord(SnakeCase)<CR>")
vim.cmd("amenu Transforms.&PascalCase :lua ReplaceCurrentWord(PascalCase)<CR>")
vim.cmd("amenu Transforms.&kebab-case :lua ReplaceCurrentWord(KebabCase)<CR>")
vim.cmd("amenu Transforms.&dot\\.case :lua ReplaceCurrentWord(DotCase)<CR>")
vim.cmd("amenu Transforms.&Title\\ Case :lua ReplaceCurrentWord(TitleCase)<CR>")
for i in TextTransform.config.keymap do
vim.keymap.set(
{ "n", "v" },
_G.TextTransform.config.keymap[i],
"<cmd>popup Transforms<CR>",
{ silent = true }
)
end

15
scripts/minimal_init.lua Normal file
View File

@@ -0,0 +1,15 @@
-- Add current directory to 'runtimepath' to be able to use 'lua' files
vim.cmd([[let &rtp.=','.getcwd()]])
-- Set up 'mini.test' and 'mini.doc' only when calling headless Neovim (like with `make test` or `make documentation`)
if #vim.api.nvim_list_uis() == 0 then
-- Add 'mini.nvim' to 'runtimepath' to be able to use 'mini.test'
-- Assumed that 'mini.nvim' is stored in 'deps/mini.nvim'
vim.cmd("set rtp+=deps/mini.nvim")
-- Set up 'mini.test'
require("mini.test").setup()
-- Set up 'mini.doc'
require("mini.doc").setup()
end

79
scripts/setup.sh Executable file
View File

@@ -0,0 +1,79 @@
#!/bin/bash
USAGE="\033[0;37m[INFO] - usage: USERNAME=my-github-username PLUGIN_NAME=my-awesome-plugin REPOSITORY_NAME=my-awesome-plugin.nvim make setup\n\033[0m"
echo -e $USAGE
if [[ -z "$USERNAME" ]]; then
echo -e "\t> No USERNAME provided, what's your GitHub/GitLab username?"
read USERNAME
fi
if [[ -z "$REPOSITORY_NAME" ]]; then
REPOSITORY_NAME=$(basename -s .git `git config --get remote.origin.url`)
read -rp $'\t> No REPOSITORY_NAME provided, is \033[1;32m'"$REPOSITORY_NAME"$'\033[0m good? [Y/n]\n' yn
case $yn in
[Yy]* );;
[Nn]* )
echo -e "\t> Enter your repository name"
read REPOSITORY_NAME
;;
* )
echo -e $USAGE
exit 1;;
esac
fi
if [[ -z "$PLUGIN_NAME" ]]; then
DEFAULT_REPOSITORY_NAME=$(echo "$REPOSITORY_NAME" | sed -e "s/\.nvim//")
read -rp $'\t> No PLUGIN_NAME provided, defaulting to \033[1;32m'"$DEFAULT_REPOSITORY_NAME"$'\033[0m, continue? [Y/n]\n' yn
case $yn in
[Yy]* )
PLUGIN_NAME=$DEFAULT_REPOSITORY_NAME
;;
[Nn]* )
echo -e "\t> Enter your plugin name"
read PLUGIN_NAME
;;
* )
echo -e $USAGE
exit 1;;
esac
fi
echo -e "Username: \033[1;32m$USERNAME\033[0m\nRepository: \033[1;32m$REPOSITORY_NAME\033[0m\nPlugin: \033[1;32m$PLUGIN_NAME\033[0m\n\n\tRenaming placeholder files..."
rm -rf doc
mv plugin/your-plugin-name.lua plugin/$PLUGIN_NAME.lua
mv lua/your-plugin-name lua/$PLUGIN_NAME
mv README_TEMPLATE.md README.md
echo -e "\tReplacing placeholder names..."
PASCAL_CASE_PLUGIN_NAME=$(echo "$PLUGIN_NAME" | perl -pe 's/(^|-)./uc($&)/ge;s/-//g')
grep -rl "YourPluginName" .github/ plugin/ tests/ lua/ | xargs sed -i "" -e "s/YourPluginName/$PASCAL_CASE_PLUGIN_NAME/g"
grep -rl "your-plugin-name" README.md .github/ plugin/ tests/ lua/ | xargs sed -i "" -e "s/your-plugin-name/$PLUGIN_NAME/g"
grep -rl "YOUR_GITHUB_USERNAME" README.md .github/ | xargs sed -i "" -e "s/YOUR_GITHUB_USERNAME/$USERNAME/g"
grep -rl "YOUR_REPOSITORY_NAME" README.md .github/ | xargs sed -i "" -e "s/YOUR_REPOSITORY_NAME/$REPOSITORY_NAME/g"
echo -e "\n\033[1;32mOK.\033[0m"
echo -e "\tFetching dependencies (tests and documentation generator)..."
make deps
echo -e "\n\033[1;32mOK.\033[0m"
echo -e "\tGenerating docs..."
make documentation
echo -e "\n\033[1;32mOK.\033[0m"
echo -e "\tRunning tests..."
make test
echo -e "\n\033[1;32mOK.\033[0m"

5
stylua.toml Normal file
View File

@@ -0,0 +1,5 @@
indent_type = "Spaces"
indent_width = 4
column_width = 100
quote_style = "AutoPreferDouble"
no_call_parentheses = false

166
tests/helpers.lua Normal file
View File

@@ -0,0 +1,166 @@
-- partially imported from https://github.com/echasnovski/mini.nvim
local Helpers = {}
-- Add extra expectations
Helpers.expect = vim.deepcopy(MiniTest.expect)
-- The error message returned when a test fails.
local function errorMessage(str, pattern)
return string.format("Pattern: %s\nObserved string: %s", vim.inspect(pattern), str)
end
-- Check equality of a global `field` against `value` in the given `child` process.
-- @usage global_equality(child, "_G.TextTransformLoaded", true)
Helpers.expect.global_equality = MiniTest.new_expectation(
"variable in child process matches",
function(child, field, value)
return Helpers.expect.equality(child.lua_get(field), value)
end,
errorMessage
)
-- Check type equality of a global `field` against `value` in the given `child` process.
-- @usage global_type_equality(child, "_G.TextTransformLoaded", "boolean")
Helpers.expect.global_type_equality = MiniTest.new_expectation(
"variable type in child process matches",
function(child, field, value)
return Helpers.expect.global_equality(child, "type(" .. field .. ")", value)
end,
errorMessage
)
-- Check equality of a config `field` against `value` in the given `child` process.
-- @usage option_equality(child, "debug", true)
Helpers.expect.config_equality = MiniTest.new_expectation(
"config option matches",
function(child, field, value)
return Helpers.expect.global_equality(child, "_G.TextTransform.config." .. field, value)
end,
errorMessage
)
-- Check type equality of a config `field` against `value` in the given `child` process.
-- @usage config_type_equality(child, "debug", "boolean")
Helpers.expect.config_type_equality = MiniTest.new_expectation(
"config option type matches",
function(child, field, value)
return Helpers.expect.global_equality(
child,
"type(_G.TextTransform.config." .. field .. ")",
value
)
end,
errorMessage
)
-- Check equality of a state `field` against `value` in the given `child` process.
-- @usage state_equality(child, "enabled", true)
Helpers.expect.state_equality = MiniTest.new_expectation(
"state matches",
function(child, field, value)
return Helpers.expect.global_equality(child, "_G.TextTransform.enabled." .. field, value)
end,
errorMessage
)
-- Check type equality of a state `field` against `value` in the given `child` process.
-- @usage state_type_equality(child, "enabled", "boolean")
Helpers.expect.state_type_equality = MiniTest.new_expectation(
"state type matches",
function(child, field, value)
return Helpers.expect.global_equality(
child,
"type(_G.TextTransform.state." .. field .. ")",
value
)
end,
errorMessage
)
Helpers.expect.match = MiniTest.new_expectation("string matching", function(str, pattern)
return str:find(pattern) ~= nil
end, errorMessage)
Helpers.expect.no_match = MiniTest.new_expectation("no string matching", function(str, pattern)
return str:find(pattern) == nil
end, errorMessage)
-- Monkey-patch `MiniTest.new_child_neovim` with helpful wrappers
Helpers.new_child_neovim = function()
local child = MiniTest.new_child_neovim()
local prevent_hanging = function(method)
-- stylua: ignore
if not child.is_blocked() then return end
local msg =
string.format("Can not use `child.%s` because child process is blocked.", method)
error(msg)
end
child.setup = function()
child.restart({ "-u", "scripts/minimal_init.lua" })
-- Change initial buffer to be readonly. This not only increases execution
-- speed, but more closely resembles manually opened Neovim.
child.bo.readonly = false
end
child.set_lines = function(arr, start, finish)
prevent_hanging("set_lines")
if type(arr) == "string" then
arr = vim.split(arr, "\n")
end
child.api.nvim_buf_set_lines(0, start or 0, finish or -1, false, arr)
end
child.get_lines = function(start, finish)
prevent_hanging("get_lines")
return child.api.nvim_buf_get_lines(0, start or 0, finish or -1, false)
end
child.set_cursor = function(line, column, win_id)
prevent_hanging("set_cursor")
child.api.nvim_win_set_cursor(win_id or 0, { line, column })
end
child.get_cursor = function(win_id)
prevent_hanging("get_cursor")
return child.api.nvim_win_get_cursor(win_id or 0)
end
child.set_size = function(lines, columns)
prevent_hanging("set_size")
if type(lines) == "number" then
child.o.lines = lines
end
if type(columns) == "number" then
child.o.columns = columns
end
end
child.get_size = function()
prevent_hanging("get_size")
return { child.o.lines, child.o.columns }
end
child.expect_screenshot = function(opts, path, screenshot_opts)
if child.fn.has("nvim-0.8") == 0 then
MiniTest.skip("Screenshots are tested for Neovim>=0.8 (for simplicity).")
end
MiniTest.expect.reference_screenshot(child.get_screenshot(screenshot_opts), path, opts)
end
return child
end
return Helpers

58
tests/test_API.lua Normal file
View File

@@ -0,0 +1,58 @@
local helpers = dofile("tests/helpers.lua")
-- See https://github.com/echasnovski/mini.nvim/blob/main/lua/mini/test.lua for more documentation
local child = helpers.new_child_neovim()
local eq_global, eq_config, eq_state =
helpers.expect.global_equality, helpers.expect.config_equality, helpers.expect.state_equality
local eq_type_global, eq_type_config, eq_type_state =
helpers.expect.global_type_equality,
helpers.expect.config_type_equality,
helpers.expect.state_type_equality
local T = MiniTest.new_set({
hooks = {
-- This will be executed before every (even nested) case
pre_case = function()
-- Restart child process with custom 'init.lua' script
child.restart({ "-u", "scripts/minimal_init.lua" })
end,
-- This will be executed one after all tests from this set are finished
post_once = child.stop,
},
})
-- Tests related to the `setup` method.
T["setup()"] = MiniTest.new_set()
T["setup()"]["sets exposed methods and default options value"] = function()
child.lua([[require('text-transform').setup()]])
-- global object that holds your plugin information
eq_type_global(child, "_G.TextTransform", "table")
-- public methods
eq_type_global(child, "_G.TextTransform.toggle", "function")
eq_type_global(child, "_G.TextTransform.disable", "function")
eq_type_global(child, "_G.TextTransform.enable", "function")
-- config
eq_type_global(child, "_G.TextTransform.config", "table")
-- assert the value, and the type
eq_config(child, "debug", false)
eq_type_config(child, "debug", "boolean")
end
T["setup()"]["overrides default values"] = function()
child.lua([[require('text-transform').setup({
-- write all the options with a value different than the default ones
debug = true,
})]])
-- assert the value, and the type
eq_config(child, "debug", true)
eq_type_config(child, "debug", "boolean")
end
return T