Skip to content

Commit e5d4ee4

Browse files
committed
test; wf; doc;
1 parent d848c0c commit e5d4ee4

File tree

14 files changed

+547
-6
lines changed

14 files changed

+547
-6
lines changed

.github/CONTRIBUTING.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,13 @@
11
## Contributiong Guidelines
22

3+
Thank you for your interest in contributing to nvim-http-client! We welcome contributions from everyone.
4+
5+
## Making Changes
6+
1. Make your changes in your branch
7+
2. Add or update tests as necessary
8+
3. Ensure all tests pass by running `make test`
9+
4. Update documentation if you're changing functionality.
10+
311
### Updating the Changelog
412

513
For every pull request, please ensure that you update the `CHANGELOG.md` file.

.github/workflows/run-tests.yml

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
name: Run Tests
2+
3+
on:
4+
push:
5+
branches: [ main ]
6+
pull_request:
7+
branches: [ main ]
8+
9+
jobs:
10+
test:
11+
runs-on: ubuntu-latest
12+
steps:
13+
- uses: actions/checkout@v3
14+
- name: Set up Neovim
15+
uses: rhysd/action-setup-vim@v1
16+
with:
17+
neovim: true
18+
version: nightly
19+
- name: Install dependencies
20+
run: |
21+
git clone --depth 1 https://github.com/nvim-lua/plenary.nvim ~/.local/share/nvim/site/pack/vendor/start/plenary.nvim
22+
git clone --depth 1 https://github.com/nvim-lua/popup.nvim ~/.local/share/nvim/site/pack/vendor/start/popup.nvim
23+
- name: Run tests
24+
run: make test
25+

CHANGELOG.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,14 @@ All notable changes to this project will be documented in this file.
55
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
66
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
77

8+
## [1.0.0] 2024-09-17
9+
### Added
10+
- Comprehensive test suite
11+
- Test created for parser, utils, init, config and health
12+
- Command to run tests
13+
- Workflow to run tests
14+
### Updated
15+
- CONTRIBUTING.md
816

917
## [1.0.0] 2024-09-16
1018
### New Features

Makefile

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
2+
.PHONY: test
3+
4+
test:
5+
nvim --headless -c "PlenaryBustedDirectory tests/http_client {minimal_init = 'tests/minimal_init.lua'}"
6+

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
11
# Neovim HTTP Request Plugin
22

3+
![Tests](https://github.com/heilgar/nvim-http-client/actions/workflows/run-tests.yml/badge.svg)
4+
35
A Neovim plugin for running HTTP requests directly from .http files, with support for environment variables. Inspired by the IntelliJ HTTP Client, this plugin brings similar functionality to Neovim in an easy-to-install and easy-to-use package.
46

57
The core goal is to ensure compatibility with .http files from IntelliJ or VSCode, allowing them to run smoothly in Neovim and vice-versa.
68

79

810
**Development is ongoing, with new features added as needed or when time permits.**
911

10-
![Lua](https://img.shields.io/badge/Made%20with%20Lua-blueviolet.svg?style=for-the-badge&logo=lua)
11-
1212
## Table of Contents
1313

1414
- [Features](#features)

lua/http_client/health.lua

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ local health = vim.health or require("health")
22

33
local M = {}
44

5-
function M.check()
5+
M.check = function()
66
health.start("http_client")
77

88
-- Check if required dependencies are available

lua/http_client/init.lua

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ local function set_keybindings()
3131
})
3232
end
3333

34-
function M.setup(opts)
34+
M.setup = function(opts)
3535
M.config.setup(opts)
3636

3737
-- Load all necessary modules
@@ -70,7 +70,7 @@ function M.setup(opts)
7070
desc = 'Run all HTTP requests in the current file.'
7171
})
7272

73-
vim.api.nvim_create_user_command('HttpStop', function()
73+
vim.api.nvim_create_user_command('HttpStop', function()
7474
M.commands.request.stop_request()
7575
end, {
7676
desc = 'Stop the currently running HTTP request.'
@@ -86,7 +86,7 @@ function M.setup(opts)
8686
desc = 'Toggle verbose mode for HTTP request.'
8787
})
8888

89-
vim.api.nvim_create_user_command('HttpDryRun', function()
89+
vim.api.nvim_create_user_command('HttpDryRun', function()
9090
M.dry_run.display_dry_run(M)
9191
end, {
9292
desc = 'Perform a dry run of the HTTP request without sending it.'

tests/http_client/config_spec.lua

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
local config = require('http_client.config')
2+
3+
describe("Config", function()
4+
before_each(function()
5+
config.setup(nil)
6+
end)
7+
8+
describe('setup', function()
9+
it('should set default options when no argumennts are passed', function()
10+
config.setup()
11+
assert.are.same(config.defaults, config.options)
12+
end)
13+
14+
it('should set non-default option', function()
15+
config.setup({foo = 'bar'})
16+
assert.are.equal(config.get('foo'), "bar")
17+
end)
18+
end)
19+
20+
describe('get', function()
21+
it('should return the correct option value', function()
22+
config.setup()
23+
assert.are.equal(config.get('default_env_file'), config.defaults.default_env_file)
24+
assert.are.equal(config.get('request_timeout'), config.defaults.request_timeout)
25+
end)
26+
27+
it('should return nil for non-existent options', function()
28+
config.setup()
29+
assert.is_nil(config.get('non_existent_option'))
30+
end)
31+
end)
32+
end)
33+
Lines changed: 221 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,221 @@
1+
local parser = require('http_client.core.parser')
2+
local environment = require('http_client.core.environment')
3+
4+
describe("Parser", function()
5+
before_each(function()
6+
-- Clear buffer content and global state before each test
7+
vim.api.nvim_buf_set_lines(0, 0, -1, false, {})
8+
end)
9+
10+
describe("get_request_under_cursor", function()
11+
it("should correctly identify and return the request under the cursor", function()
12+
-- Setup buffer content
13+
local buffer_content = {
14+
"### Test 1",
15+
"GET /test1 HTTP/1.1",
16+
"Header1: Value1",
17+
"",
18+
"Body1",
19+
"### Test 2",
20+
"POST /test2 HTTP/1.1",
21+
"Header2: Value2",
22+
"",
23+
"Body2"
24+
}
25+
vim.api.nvim_buf_set_lines(0, 0, -1, false, buffer_content)
26+
vim.api.nvim_win_set_cursor(0, { 2, 0 }) -- Cursor on the first request
27+
28+
local request = parser.get_request_under_cursor()
29+
assert.is_not_nil(request)
30+
assert.are.equal(request.method, "GET")
31+
assert.are.equal(request.url, "/test1")
32+
assert.are.equal(request.body, "Body1")
33+
end)
34+
35+
it("should handle cases where cursor is on line before separator", function()
36+
local buffer_content = {
37+
"### Test 1",
38+
"GET /test1 HTTP/1.1",
39+
"",
40+
"### Test 2",
41+
"POST /test2 HTTP/1.1",
42+
""
43+
}
44+
vim.api.nvim_buf_set_lines(0, 0, -1, false, buffer_content)
45+
vim.api.nvim_win_set_cursor(0, { 3, 0 }) -- Cursor on the empty line after first request
46+
47+
local request = parser.get_request_under_cursor()
48+
assert.is_not_nil(request)
49+
assert.are.equal(request.method, "GET") -- Expect the next request
50+
assert.are.equal(request.url, "/test1")
51+
end)
52+
53+
it("should handle cases where cursor is directly on a separator", function()
54+
local buffer_content = {
55+
"### Test 1",
56+
"GET /test1 HTTP/1.1",
57+
"",
58+
"### Test 2",
59+
"POST /test2 HTTP/1.1",
60+
""
61+
}
62+
vim.api.nvim_buf_set_lines(0, 0, -1, false, buffer_content)
63+
vim.api.nvim_win_set_cursor(0, { 4, 0 }) -- Cursor on the "### Test 2" line
64+
local request = parser.get_request_under_cursor()
65+
assert.is_not_nil(request)
66+
assert.are.equal(request.method, "POST")
67+
assert.are.equal(request.url, "/test2")
68+
assert.are.equal(request.test_name, "Test 2")
69+
end)
70+
71+
it("should return an empty request if there are no requests", function()
72+
vim.api.nvim_buf_set_lines(0, 0, -1, false, {})
73+
local request = parser.get_request_under_cursor()
74+
assert.is_not_nil(request)
75+
assert.are.same(request, { headers = {}, test_name = '' })
76+
end)
77+
end)
78+
79+
describe("parse_request", function()
80+
it("should correctly parse a request from lines", function()
81+
local lines = {
82+
"GET /test HTTP/1.1",
83+
"Header1: Value1",
84+
"Header2: Value2",
85+
"",
86+
"Body"
87+
}
88+
89+
local request = parser.parse_request(lines)
90+
assert.are.equal(request.method, "GET")
91+
assert.are.equal(request.url, "/test")
92+
assert.are.equal(request.http_version, "HTTP/1.1")
93+
assert.are.same(request.headers, { Header1 = "Value1", Header2 = "Value2" })
94+
assert.are.equal(request.body, "Body")
95+
end)
96+
97+
it("should parse a basic GET request", function()
98+
local lines = {
99+
"GET https://api.example.com/users HTTP/1.1",
100+
"Host: api.example.com",
101+
"User-Agent: TestClient/1.0",
102+
""
103+
}
104+
local request = parser.parse_request(lines)
105+
assert.are.same({
106+
method = "GET",
107+
url = "https://api.example.com/users",
108+
headers = {
109+
["Host"] = "api.example.com",
110+
["User-Agent"] = "TestClient/1.0"
111+
},
112+
body = nil,
113+
http_version = "HTTP/1.1"
114+
}, request)
115+
end)
116+
117+
it("should parse a POST request with body", function()
118+
local lines = {
119+
"POST https://api.example.com/users HTTP/1.1",
120+
"Host: api.example.com",
121+
"Content-Type: application/json",
122+
"",
123+
'{"name": "John Doe", "email": "[email protected]"}'
124+
}
125+
local request = parser.parse_request(lines)
126+
assert.are.same({
127+
method = "POST",
128+
url = "https://api.example.com/users",
129+
headers = {
130+
["Host"] = "api.example.com",
131+
["Content-Type"] = "application/json"
132+
},
133+
body = '{"name": "John Doe", "email": "[email protected]"}',
134+
http_version = "HTTP/1.1"
135+
}, request)
136+
end)
137+
138+
it("should parse a request without HTTP version", function()
139+
local lines = {
140+
"GET https://api.example.com/users",
141+
"Host: api.example.com",
142+
""
143+
}
144+
local request = parser.parse_request(lines)
145+
assert.are.same({
146+
method = "GET",
147+
url = "https://api.example.com/users",
148+
headers = {
149+
["Host"] = "api.example.com"
150+
},
151+
body = nil,
152+
http_version = "HTTP/1.1" -- Default version
153+
}, request)
154+
end)
155+
156+
it("should parse a request with response handler", function()
157+
local lines = {
158+
"GET https://api.example.com/users HTTP/1.1",
159+
"Host: api.example.com",
160+
"",
161+
"> {% ",
162+
"print(response.body)",
163+
"%}"
164+
}
165+
local request = parser.parse_request(lines)
166+
assert.are.same({
167+
method = "GET",
168+
url = "https://api.example.com/users",
169+
headers = {
170+
["Host"] = "api.example.com"
171+
},
172+
body = nil,
173+
http_version = "HTTP/1.1",
174+
response_handler = "print(response.body)\n"
175+
}, request)
176+
end)
177+
end)
178+
179+
describe("parse_all_requests", function()
180+
it("should parse multiple requests correctly", function()
181+
local lines = {
182+
"### Test 1",
183+
"GET /test1 HTTP/1.1",
184+
"Header1: Value1",
185+
"",
186+
"Body1",
187+
"### Test 2",
188+
"POST /test2 HTTP/1.1",
189+
"Header2: Value2",
190+
"",
191+
"Body2"
192+
}
193+
194+
local requests = parser.parse_all_requests(lines)
195+
assert.are.equal(#requests, 2)
196+
assert.are.equal(requests[1].method, "GET")
197+
assert.are.equal(requests[1].url, "/test1")
198+
assert.are.equal(requests[2].method, "POST")
199+
assert.are.equal(requests[2].url, "/test2")
200+
end)
201+
end)
202+
203+
describe("replace_placeholders", function()
204+
it("should replace placeholders with environment variables", function()
205+
local env = {
206+
TEST_URL = "http://example.com"
207+
}
208+
local request = {
209+
url = "{{TEST_URL}}/path",
210+
headers = { Host = "{{TEST_URL}}" },
211+
body = "Body with {{TEST_URL}}"
212+
}
213+
214+
local replaced_request = parser.replace_placeholders(request, env)
215+
assert.are.equal(replaced_request.url, "http://example.com/path")
216+
assert.are.equal(replaced_request.headers.Host, "http://example.com")
217+
assert.are.equal(replaced_request.body, "Body with http://example.com")
218+
end)
219+
end)
220+
end)
221+

0 commit comments

Comments
 (0)