feat: cmd select environment file - #247
Conversation
Review or Edit in CodeSandboxOpen the branch in Web Editor • VS Code • Insiders |
|
WalkthroughThe changes update documentation and code to introduce a new Changes
Sequence Diagram(s)sequenceDiagram
participant User
participant Neovim
participant HurlPlugin
User->>Neovim: :HurlSelectEnvFile
Neovim->>HurlPlugin: Call HurlSelectEnvFile command
HurlPlugin->>HurlPlugin: Search for env files matching env_pattern
alt Files found
HurlPlugin->>User: Show selection prompt
User->>HurlPlugin: Select env file
HurlPlugin->>HurlPlugin: register_env_file(selected_path)
HurlPlugin->>User: Notify env file registered
else No files found
HurlPlugin->>User: Notify no env files found
end
Suggested reviewers
Poem
📜 Recent review detailsConfiguration used: CodeRabbit UI 📒 Files selected for processing (4)
🚧 Files skipped from review as they are similar to previous changes (2)
🧰 Additional context used🪛 LanguageToolREADME.md[typographical] ~148-~148: Two consecutive commas (DOUBLE_PUNCTUATION) doc/hurl.nvim.txt[uncategorized] ~194-~194: Possible missing article found. (AI_HYDRA_LEO_MISSING_THE) ✨ Finishing Touches
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
SupportNeed help? Create a ticket on our support page for assistance with any issues or questions. Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
There was a problem hiding this comment.
Summary of Changes
Hello @htquangg, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed!
This pull request introduces a new command and configuration option to enhance the environment file selection process in the Hurl Neovim plugin. The HurlSelectEnvFile command provides an interactive way to choose environment files, while the env_pattern configuration allows users to customize the file search pattern.
Highlights
- New Command: HurlSelectEnvFile: Introduces a new command
HurlSelectEnvFileto simplify the selection of environment files for Hurl tests. This command allows users to interactively choose an environment file from a list of detected files. - Environment File Pattern: Adds a new configuration option
env_patternto customize the pattern used to find environment files. This allows users to specify a custom regex to match their environment file names. - Register Environment File Function: Introduces a new function
register_env_fileto register the selected environment file, splitting the path by commas to support multiple files.
Using Gemini Code Assist
The full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips.
Invoking Gemini
You can request assistance from Gemini at any point in your pull request via creating an issue comment (i.e. comment on the pull request page) using either /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands.
| Feature | Command | Description |
|---|---|---|
| Code Review | /gemini review |
Performs a code review for the current pull request in its current state. |
| Pull Request Summary | /gemini summary |
Provides a summary of the current pull request in its current state. |
| Comment | @gemini-code-assist | Responds in comments when explicitly tagged, both in issue comments and review comments. |
| Help | /gemini help |
Displays a list of available commands. |
Customization
To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a .gemini/ folder in the base of the repository. Detailed instructions can be found here.
Limitations & Feedback
Gemini Code Assist is currently in preview and may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments to provide feedback.
You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension.
Footnotes
-
Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution. ↩
There was a problem hiding this comment.
Caution
Changes requested ❌
Reviewed everything up to 1be249e in 1 minute and 42 seconds. Click for details.
- Reviewed
144lines of code in5files - Skipped
0files when reviewing. - Skipped posting
5draft comments. View those below. - Modify your settings and rules to customize what types of comments Ellipsis leaves. And don't forget to react with 👍 or 👎 to teach Ellipsis.
1. lua/hurl/main.lua:99
- Draft comment:
In the select_env_file function, consider handling the case when no environment files are found (empty list), to provide a clearer message to the user. - Reason this comment was not posted:
Decided after close inspection that this draft comment was likely wrong and/or not actionable: usefulness confidence = 20% vs. threshold = 50% 1. The comment points out a real edge case that isn't explicitly handled 2. vim.ui.select() behavior with empty list isn't clear from this code 3. However, this seems like a minor edge case - if no env files exist, nothing bad will happen 4. The comment isn't suggesting a critical bug fix, just a nice-to-have UX improvement 5. Without seeing utils.find_env_files() implementation, we can't be fully certain this is an issue I may be underestimating the importance of good UX around env file selection. A confusing UI when no files exist could frustrate users. While good UX is important, this seems like a minor edge case that wouldn't significantly impact users. The current behavior is likely fine - users will understand if no files appear in the selection UI. This comment suggests a minor UX improvement rather than fixing a real bug. Without more context about utils.find_env_files(), we can't be fully confident this needs fixing.
2. lua/hurl/main.lua:91
- Draft comment:
The register_env_file function splits the provided path by comma. Ensure that if future changes allow passing a table, the behavior remains consistent. - Reason this comment was not posted:
Confidence changes required:50%<= threshold50%None
3. lua/hurl/utils.lua:355
- Draft comment:
find_env_files uses _HURL_GLOBAL_CONFIG.env_pattern for matching filenames. It might be safer to validate that env_pattern is non-nil, in case of misconfiguration. - Reason this comment was not posted:
Confidence changes required:50%<= threshold50%None
4. lua/hurl/utils.lua:145
- Draft comment:
The function is_nightly returns true when nvim version is >= 0.11.0. The naming could be misleading since it's checking version, not whether the build is nightly. Consider a clearer name. - Reason this comment was not posted:
Comment was not on a location in the diff, so it can't be submitted as a review comment.
5. lua/hurl/utils.lua:308
- Draft comment:
In get_storage_path, mkdir is called to create the storage directory. Adding error handling here (or logging if mkdir fails) could improve robustness. - Reason this comment was not posted:
Confidence changes required:40%<= threshold50%None
Workflow ID: wflow_rS4hiziJ0KLhzuCu
You can customize by changing your verbosity settings, reacting with 👍 or 👎, replying to comments, or adding code review rules.
| -- Select the env file | ||
| utils.create_cmd('HurlSelectEnvFile', function() | ||
| select_env_file() | ||
| end, { nargs = '*', range = true }) |
There was a problem hiding this comment.
For a command that does not require arguments (HurlSelectEnvFile), consider using 'nargs = 0' instead of '*' to avoid unexpected parameter handling.
| end, { nargs = '*', range = true }) | |
| end, { nargs = 0, range = true }) |
There was a problem hiding this comment.
Code Review
This pull request introduces a new HurlSelectEnvFile command, allowing users to select an environment file. The changes include adding the new command, updating documentation, and adding a utility function. The review focuses on improving correctness and consistency.
| M.find_env_files = function() | ||
| return vim.fs.find(function(name, _) | ||
| return name:match(_HURL_GLOBAL_CONFIG.env_pattern) | ||
| end, { | ||
| path = vim.fn.expand('%:h'), | ||
| upward = true, | ||
| stop = vim.fn.getcwd(), | ||
| type = 'file', | ||
| limit = math.huge, | ||
| }) |
There was a problem hiding this comment.
The new find_env_files function introduces an inconsistency in how environment files are discovered within the plugin. It uses the new env_pattern configuration to find files, which is only used by the new HurlSelectEnvFile command. Other parts of the plugin, like the HurlManageVariable command, still use the older find_env_files_in_folders function, which has a different discovery logic and doesn't respect the new env_pattern. To ensure consistent behavior, unify the environment file discovery logic across the plugin, so that all commands that deal with environment files use this new find_env_files function and the env_pattern.
There was a problem hiding this comment.
This is valid point @htquangg Could you take a look? Thanks.
|
|
||
| To change the environment file name, use the `HurlSetEnvFile` command followed by the new file name. You can have multiple variable files by having comma-separated values. | ||
|
|
||
| Another way, use the `HurlSelectEnvFile` command to select and register environment file. |
There was a problem hiding this comment.
| by the new file name. You can have multiple variable files by having | ||
| comma-separated values. | ||
|
|
||
| Another way, use the `HurlSelectEnvFile` command to select and register environment file. |
| utils.notify('hurl: env file changed to ' .. updated_env, vim.log.levels.INFO) | ||
| end | ||
|
|
||
| ---@return string? path |
There was a problem hiding this comment.
| -- Select the env file | ||
| utils.create_cmd('HurlSelectEnvFile', function() | ||
| select_env_file() | ||
| end, { nargs = '*', range = true }) |
There was a problem hiding this comment.
There was a problem hiding this comment.
Actionable comments posted: 2
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (5)
README.md(3 hunks)doc/hurl.nvim.txt(3 hunks)lua/hurl/init.lua(1 hunks)lua/hurl/main.lua(2 hunks)lua/hurl/utils.lua(1 hunks)
🔇 Additional comments (8)
lua/hurl/init.lua (1)
18-18: LGTM! Configuration pattern looks correct.The
env_patternconfiguration uses proper Lua pattern syntax with escaped dot (%.) and is well-integrated into the default configuration.README.md (3)
148-149: Clear documentation for the new command.The addition properly documents the alternative method for selecting environment files.
314-314: Good addition to configuration documentation.The
env_patternoption is properly included in the default configuration example.
355-355: Helpful comment for the configuration option.The inline comment clearly explains the purpose of the
env_patternsetting.doc/hurl.nvim.txt (2)
194-194: Consistent with README documentation.The vim help file properly documents the new command functionality.
392-392: Configuration documentation is complete.Both the default configuration and setup example properly include the new
env_patternoption.Also applies to: 433-433
lua/hurl/main.lua (2)
87-96: Good refactoring to centralize env file registration.The function properly handles comma-separated paths and provides user feedback through logging and notifications.
173-180: Clean command implementation using helper functions.Both commands properly utilize the helper functions and maintain consistency with the existing command patterns.
| ---Find a list of environment files | ||
| ---@see rest.Opts.Env.find | ||
| ---@return string[] files Environment variable files path | ||
| M.find_env_files = function() | ||
| return vim.fs.find(function(name, _) | ||
| return name:match(_HURL_GLOBAL_CONFIG.env_pattern) | ||
| end, { | ||
| path = vim.fn.expand('%:h'), | ||
| upward = true, | ||
| stop = vim.fn.getcwd(), | ||
| type = 'file', | ||
| limit = math.huge, | ||
| }) | ||
| end |
There was a problem hiding this comment.
🛠️ Refactor suggestion
Add error handling for pattern matching.
The function should handle cases where the pattern might be invalid or _HURL_GLOBAL_CONFIG.env_pattern is nil.
M.find_env_files = function()
+ local pattern = _HURL_GLOBAL_CONFIG.env_pattern
+ if not pattern or type(pattern) ~= 'string' then
+ M.log_error('Invalid env_pattern configuration')
+ return {}
+ end
+
return vim.fs.find(function(name, _)
- return name:match(_HURL_GLOBAL_CONFIG.env_pattern)
+ local ok, result = pcall(string.match, name, pattern)
+ return ok and result
end, {
path = vim.fn.expand('%:h'),
upward = true,
stop = vim.fn.getcwd(),
type = 'file',
limit = math.huge,
})
end📝 Committable suggestion
‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.
| ---Find a list of environment files | |
| ---@see rest.Opts.Env.find | |
| ---@return string[] files Environment variable files path | |
| M.find_env_files = function() | |
| return vim.fs.find(function(name, _) | |
| return name:match(_HURL_GLOBAL_CONFIG.env_pattern) | |
| end, { | |
| path = vim.fn.expand('%:h'), | |
| upward = true, | |
| stop = vim.fn.getcwd(), | |
| type = 'file', | |
| limit = math.huge, | |
| }) | |
| end | |
| ---Find a list of environment files | |
| ---@see rest.Opts.Env.find | |
| ---@return string[] files Environment variable files path | |
| M.find_env_files = function() | |
| local pattern = _HURL_GLOBAL_CONFIG.env_pattern | |
| if not pattern or type(pattern) ~= 'string' then | |
| M.log_error('Invalid env_pattern configuration') | |
| return {} | |
| end | |
| return vim.fs.find(function(name, _) | |
| local ok, result = pcall(string.match, name, pattern) | |
| return ok and result | |
| end, { | |
| path = vim.fn.expand('%:h'), | |
| upward = true, | |
| stop = vim.fn.getcwd(), | |
| type = 'file', | |
| limit = math.huge, | |
| }) | |
| end |
🤖 Prompt for AI Agents
In lua/hurl/utils.lua around lines 352 to 365, the function M.find_env_files
uses pattern matching without checking if _HURL_GLOBAL_CONFIG.env_pattern is
valid or nil. Add a check before the vim.fs.find call to ensure
_HURL_GLOBAL_CONFIG.env_pattern is a non-nil string. Also, wrap the pattern
matching in pcall or use xpcall to catch any errors from invalid patterns and
handle them gracefully, such as returning an empty list or logging an error.
27b50ed to
accb7b8
Compare
for more information, see https://pre-commit.ci
Docstrings generation was requested by @jellydn. * #247 (comment) The following files were modified: * `lua/hurl/main.lua`
|
Note Generated docstrings for this pull request at #248 |
|
Note Unit test generation is an Early Access feature. Expect some limitations and changes as we gather feedback and continue to improve it. Generating unit tests... This may take up to 20 minutes. |
|
Here are the copyable unit test edits: Copyable Editstest/hurl_spec.lua@@ -1,15 +1,570 @@
ocal hurl = require('hurl.main')
escribe('Hurl wrapper', function()
- it('should be able to load', function()
- assert.truthy(hurl)
+ -- Setup and teardown
+ before_each(function()
+ -- Reset any global state or mocks
+ _HURL_GLOBAL_CONFIG = _HURL_GLOBAL_CONFIG or {}
+ vim.fn = vim.fn or {}
+ vim.api = vim.api or {}
+ vim.cmd = vim.cmd or function() end
+ vim.log = vim.log or { levels = { INFO = 1, WARN = 2, ERROR = 3 } }
+ vim.defer_fn = vim.defer_fn or function(fn, delay) fn() end
+ vim.ui = vim.ui or {}
+ vim.fs = vim.fs or {}
end)
- it('should define a custom command: HurlRunner', function()
- assert.truthy(vim.fn.exists(':HurlRunner'))
+ after_each(function()
+ -- Clean up any test state
+ _HURL_GLOBAL_CONFIG = {}
end)
- it('should define a custom command: HurlRunnerAt', function()
- assert.truthy(vim.fn.exists(':HurlRunnerAt'))
+ describe('module loading', function()
+ it('should be able to load', function()
+ assert.truthy(hurl)
+ end)
+
+ it('should be a table', function()
+ assert.is.table(hurl)
+ end)
+
+ it('should not be empty', function()
+ assert.is_not.same({}, hurl)
+ end)
+
+ it('should expose setup function', function()
+ assert.is.function(hurl.setup)
+ end)
+ end)
+
+ describe('setup function', function()
+ local original_create_cmd
+ local commands_created = {}
+
+ before_each(function()
+ commands_created = {}
+ -- Mock utils.create_cmd to track command creation
+ local utils = require('hurl.utils')
+ original_create_cmd = utils.create_cmd
+ utils.create_cmd = function(name, fn, opts)
+ commands_created[name] = { fn = fn, opts = opts }
+ vim.fn['exists'] = function(cmd)
+ return ':' .. name == cmd and 1 or 0
+ end
+ end
+ end)
+
+ after_each(function()
+ if original_create_cmd then
+ local utils = require('hurl.utils')
+ utils.create_cmd = original_create_cmd
+ end
+ end)
+
+ it('should create all required commands', function()
+ hurl.setup()
+
+ local expected_commands = {
+ 'HurlRunner',
+ 'HurlRunnerAt',
+ 'HurlRunnerToEntry',
+ 'HurlToggleMode',
+ 'HurlSetEnvFile',
+ 'HurlSelectEnvFile',
+ 'HurlVerbose',
+ 'HurlVeryVerbose',
+ 'HurlJson',
+ 'HurlSetVariable',
+ 'HurlManageVariable',
+ 'HurlDebugInfo',
+ 'HurlShowLastResponse',
+ 'HurlRunnerToEnd',
+ 'HurlRerun'
+ }
+
+ for _, cmd in ipairs(expected_commands) do
+ assert.truthy(commands_created[cmd], 'Command ' .. cmd .. ' should be created')
+ end
+ end)
+
+ it('should set up codelens', function()
+ local codelens = require('hurl.codelens')
+ local setup_called = false
+ codelens.setup = function() setup_called = true end
+
+ hurl.setup()
+
+ assert.is_true(setup_called)
+ end)
+
+ it('should handle setup multiple times', function()
+ assert.has_no.errors(function()
+ hurl.setup()
+ hurl.setup()
+ hurl.setup()
+ end)
+ end)
+ end)
+
+ describe('custom commands functionality', function()
+ local mock_utils, mock_http, mock_hurl_runner
+
+ before_each(function()
+ -- Mock dependencies
+ mock_utils = {
+ create_cmd = function(name, fn, opts)
+ vim.fn['exists'] = function(cmd) return ':' .. name == cmd and 1 or 0 end
+ end,
+ get_visual_selection = function() return {'GET https://example.com'} end,
+ create_tmp_file = function() return '/tmp/test.hurl' end,
+ log_info = function() end,
+ log_warn = function() end,
+ notify = function() end,
+ is_nightly = function() return false end,
+ is_hurl_parser_available = false
+ }
+
+ mock_http = {
+ find_hurl_entry_positions_in_buffer = function()
+ return {current = 1, start_line = 1, end_line = 5}
+ end,
+ find_http_verb_positions_in_buffer = function()
+ return {current = 1, start_line = 1, end_line = 5}
+ end
+ }
+
+ mock_hurl_runner = {
+ execute_hurl_cmd = function() end,
+ run_hurl_verbose = function() end
+ }
+
+ -- Mock vim functions
+ vim.fn.expand = function(arg)
+ if arg == '%:p' then return '/path/to/test.hurl' end
+ if arg == '%:h' then return '/path/to' end
+ return arg
+ end
+
+ vim.fn.getcwd = function() return '/project' end
+ vim.fn.filereadable = function() return 1 end
+
+ -- Replace requires
+ package.loaded['hurl.utils'] = mock_utils
+ package.loaded['hurl.http_utils'] = mock_http
+ package.loaded['hurl.lib.hurl_runner'] = mock_hurl_runner
+ end)
+
+ describe('HurlRunner command', function()
+ it('should handle file execution', function()
+ local execute_called = false
+ mock_hurl_runner.execute_hurl_cmd = function(opts)
+ execute_called = true
+ assert.truthy(opts)
+ assert.is.table(opts)
+ end
+
+ hurl.setup()
+ local cmd_fn = commands_created['HurlRunner'].fn
+ cmd_fn({range = 0, fargs = {}})
+
+ assert.is_true(execute_called)
+ end)
+
+ it('should handle selection execution', function()
+ local execute_called = false
+ mock_hurl_runner.execute_hurl_cmd = function(opts)
+ execute_called = true
+ assert.truthy(opts)
+ end
+
+ hurl.setup()
+ local cmd_fn = commands_created['HurlRunner'].fn
+ cmd_fn({range = 1, fargs = {}})
+
+ assert.is_true(execute_called)
+ end)
+
+ it('should handle empty selection gracefully', function()
+ mock_utils.get_visual_selection = function() return nil end
+
+ hurl.setup()
+ local cmd_fn = commands_created['HurlRunner'].fn
+
+ assert.has_no.errors(function()
+ cmd_fn({range = 1, fargs = {}})
+ end)
+ end)
+
+ it('should handle tmp file creation failure', function()
+ mock_utils.create_tmp_file = function() return nil end
+
+ hurl.setup()
+ local cmd_fn = commands_created['HurlRunner'].fn
+
+ assert.has_no.errors(function()
+ cmd_fn({range = 1, fargs = {}})
+ end)
+ end)
+ end)
+
+ describe('HurlRunnerAt command', function()
+ it('should execute at current line when HTTP method found', function()
+ local execute_called = false
+ mock_hurl_runner.execute_hurl_cmd = function(opts)
+ execute_called = true
+ assert.truthy(opts)
+ assert.is.table(opts)
+ end
+
+ hurl.setup()
+ local cmd_fn = commands_created['HurlRunnerAt'].fn
+ cmd_fn({fargs = {}})
+
+ assert.is_true(execute_called)
+ end)
+
+ it('should handle no HTTP method found', function()
+ mock_http.find_hurl_entry_positions_in_buffer = function()
+ return {current = 0, start_line = nil, end_line = nil}
+ end
+ mock_http.find_http_verb_positions_in_buffer = function()
+ return {current = 0, start_line = nil, end_line = nil}
+ end
+
+ hurl.setup()
+ local cmd_fn = commands_created['HurlRunnerAt'].fn
+
+ assert.has_no.errors(function()
+ cmd_fn({fargs = {}})
+ end)
+ end)
+ end)
+
+ describe('HurlToggleMode command', function()
+ it('should toggle from split to popup', function()
+ _HURL_GLOBAL_CONFIG.mode = 'split'
+
+ hurl.setup()
+ local cmd_fn = commands_created['HurlToggleMode'].fn
+ cmd_fn()
+
+ assert.is.equal('popup', _HURL_GLOBAL_CONFIG.mode)
+ end)
+
+ it('should toggle from popup to split', function()
+ _HURL_GLOBAL_CONFIG.mode = 'popup'
+
+ hurl.setup()
+ local cmd_fn = commands_created['HurlToggleMode'].fn
+ cmd_fn()
+
+ assert.is.equal('split', _HURL_GLOBAL_CONFIG.mode)
+ end)
+
+ it('should handle undefined mode', function()
+ _HURL_GLOBAL_CONFIG.mode = nil
+
+ hurl.setup()
+ local cmd_fn = commands_created['HurlToggleMode'].fn
+
+ assert.has_no.errors(function()
+ cmd_fn()
+ end)
+
+ assert.is.equal('popup', _HURL_GLOBAL_CONFIG.mode)
+ end)
+ end)
+
+ describe('HurlSetEnvFile command', function()
+ it('should set environment file', function()
+ hurl.setup()
+ local cmd_fn = commands_created['HurlSetEnvFile'].fn
+ cmd_fn({fargs = {'.env.test'}})
+
+ assert.is.table(_HURL_GLOBAL_CONFIG.env_file)
+ assert.is.equal('.env.test', _HURL_GLOBAL_CONFIG.env_file[1])
+ end)
+
+ it('should handle multiple environment files', function()
+ hurl.setup()
+ local cmd_fn = commands_created['HurlSetEnvFile'].fn
+ cmd_fn({fargs = {'.env.test,.env.local'}})
+
+ assert.is.table(_HURL_GLOBAL_CONFIG.env_file)
+ assert.is.equal(2, #_HURL_GLOBAL_CONFIG.env_file)
+ end)
+
+ it('should handle no environment file provided', function()
+ hurl.setup()
+ local cmd_fn = commands_created['HurlSetEnvFile'].fn
+
+ assert.has_no.errors(function()
+ cmd_fn({fargs = {}})
+ end)
+ end)
+ end)
+
+ describe('HurlSetVariable command', function()
+ it('should set global variable', function()
+ hurl.setup()
+ local cmd_fn = commands_created['HurlSetVariable'].fn
+ cmd_fn({fargs = {'test_var', 'test_value'}})
+
+ assert.is.table(_HURL_GLOBAL_CONFIG.global_vars)
+ assert.is.equal('test_value', _HURL_GLOBAL_CONFIG.global_vars['test_var'])
+ end)
+
+ it('should handle missing variable name', function()
+ hurl.setup()
+ local cmd_fn = commands_created['HurlSetVariable'].fn
+
+ assert.has_no.errors(function()
+ cmd_fn({fargs = {}})
+ end)
+ end)
+
+ it('should handle missing variable value', function()
+ hurl.setup()
+ local cmd_fn = commands_created['HurlSetVariable'].fn
+
+ assert.has_no.errors(function()
+ cmd_fn({fargs = {'test_var'}})
+ end)
+ end)
+ end)
+
+ describe('HurlVerbose and HurlVeryVerbose commands', function()
+ it('should run verbose command with current entry', function()
+ local verbose_called = false
+ mock_hurl_runner.run_hurl_verbose = function(filePath, fromEntry, toEntry, isVeryVerbose)
+ verbose_called = true
+ assert.is.string(filePath)
+ assert.is.number(fromEntry)
+ assert.is.number(toEntry)
+ assert.is.boolean(isVeryVerbose)
+ end
+
+ hurl.setup()
+ local cmd_fn = commands_created['HurlVerbose'].fn
+ cmd_fn({fargs = {}})
+
+ assert.is_true(verbose_called)
+ end)
+
+ it('should run very verbose command', function()
+ local very_verbose_called = false
+ mock_hurl_runner.run_hurl_verbose = function(filePath, fromEntry, toEntry, isVeryVerbose)
+ very_verbose_called = true
+ assert.is_true(isVeryVerbose)
+ end
+
+ hurl.setup()
+ local cmd_fn = commands_created['HurlVeryVerbose'].fn
+ cmd_fn({fargs = {}})
+
+ assert.is_true(very_verbose_called)
+ end)
+
+ it('should handle custom entry range', function()
+ local verbose_called = false
+ mock_hurl_runner.run_hurl_verbose = function(filePath, fromEntry, toEntry, isVeryVerbose)
+ verbose_called = true
+ assert.is.equal(2, fromEntry)
+ assert.is.equal(5, toEntry)
+ end
+
+ hurl.setup()
+ local cmd_fn = commands_created['HurlVerbose'].fn
+ cmd_fn({fargs = {'2', '5'}})
+
+ assert.is_true(verbose_called)
+ end)
+ end)
+
+ describe('HurlRerun command', function()
+ it('should rerun last command', function()
+ -- First run a command to set last_from_entry
+ hurl.setup()
+ local run_at_cmd = commands_created['HurlRunnerAt'].fn
+ run_at_cmd({fargs = {}})
+
+ -- Then test rerun
+ local rerun_called = false
+ mock_hurl_runner.execute_hurl_cmd = function(opts)
+ rerun_called = true
+ assert.truthy(opts)
+ end
+
+ local cmd_fn = commands_created['HurlRerun'].fn
+ cmd_fn()
+
+ assert.is_true(rerun_called)
+ end)
+
+ it('should handle no previous command', function()
+ hurl.setup()
+ local cmd_fn = commands_created['HurlRerun'].fn
+
+ assert.has_no.errors(function()
+ cmd_fn()
+ end)
+ end)
+ end)
+ end)
+
+ describe('error handling and edge cases', function()
+ before_each(function()
+ vim.fn.expand = function() error('File system error') end
+ end)
+
+ it('should handle file system errors gracefully', function()
+ assert.has_no.errors(function()
+ hurl.setup()
+ end)
+ end)
+
+ it('should handle missing dependencies gracefully', function()
+ -- Temporarily break require
+ local original_require = require
+ require = function(module)
+ if module:match('hurl%.') then
+ error('Module not found: ' .. module)
+ end
+ return original_require(module)
+ end
+
+ assert.has_no.errors(function()
+ pcall(hurl.setup)
+ end)
+
+ -- Restore require
+ require = original_require
+ end)
+ end)
+
+ describe('integration scenarios', function()
+ before_each(function()
+ -- Set up complete mock environment
+ local utils = require('hurl.utils')
+ utils.create_cmd = function(name, fn, opts)
+ vim.fn['exists'] = function(cmd) return ':' .. name == cmd and 1 or 0 end
+ end
+ utils.get_visual_selection = function()
+ return {
+ 'GET https://api.example.com/users',
+ 'Accept: application/json',
+ 'Authorization: Bearer {{token}}'
+ }
+ end
+ utils.create_tmp_file = function() return '/tmp/hurl_test.hurl' end
+ utils.log_info = function() end
+ utils.notify = function() end
+ end)
+
+ it('should handle complex hurl workflow', function()
+ hurl.setup()
+
+ -- Set a variable
+ local set_var_cmd = commands_created['HurlSetVariable'].fn
+ set_var_cmd({fargs = {'base_url', 'https://api.example.com'}})
+
+ -- Toggle mode
+ local toggle_cmd = commands_created['HurlToggleMode'].fn
+ toggle_cmd()
+
+ -- Run a request
+ local run_cmd = commands_created['HurlRunner'].fn
+
+ assert.has_no.errors(function()
+ run_cmd({range = 0, fargs = {}})
+ end)
+ end)
+
+ it('should handle environment file workflow', function()
+ hurl.setup()
+
+ -- Set environment file
+ local env_cmd = commands_created['HurlSetEnvFile'].fn
+ env_cmd({fargs = {'.env.test'}})
+
+ -- Set variables
+ local var_cmd = commands_created['HurlSetVariable'].fn
+ var_cmd({fargs = {'api_key', 'test123'}})
+ var_cmd({fargs = {'base_url', 'https://test.api.com'}})
+
+ assert.is.equal('.env.test', _HURL_GLOBAL_CONFIG.env_file[1])
+ assert.is.equal('test123', _HURL_GLOBAL_CONFIG.global_vars['api_key'])
+ assert.is.equal('https://test.api.com', _HURL_GLOBAL_CONFIG.global_vars['base_url'])
+ end)
+ end)
+
+ describe('performance and stress tests', function()
+ it('should handle rapid command execution', function()
+ hurl.setup()
+
+ local start_time = os.clock()
+
+ for i = 1, 100 do
+ local toggle_cmd = commands_created['HurlToggleMode'].fn
+ toggle_cmd()
+ end
+
+ local end_time = os.clock()
+ assert.is_true((end_time - start_time) < 1, 'Should complete toggles within 1 second')
+ end)
+
+ it('should handle many variable assignments', function()
+ hurl.setup()
+
+ local start_time = os.clock()
+ local var_cmd = commands_created['HurlSetVariable'].fn
+
+ for i = 1, 1000 do
+ var_cmd({fargs = {'var' .. i, 'value' .. i}})
+ end
+
+ local end_time = os.clock()
+ assert.is_true((end_time - start_time) < 2, 'Should complete variable assignments within 2 seconds')
+ assert.is.equal(1000, vim.tbl_count(_HURL_GLOBAL_CONFIG.global_vars))
+ end)
+ end)
+
+ -- Legacy tests (keeping for compatibility)
+ describe('command existence (legacy)', function()
+ before_each(function()
+ hurl.setup()
+ end)
+
+ it('should define a custom command: HurlRunner', function()
+ assert.truthy(vim.fn.exists(':HurlRunner'))
+ end)
+
+ it('should define a custom command: HurlRunnerAt', function()
+ assert.truthy(vim.fn.exists(':HurlRunnerAt'))
+ end)
+
+ it('should define a custom command: HurlToggleMode', function()
+ assert.truthy(vim.fn.exists(':HurlToggleMode'))
+ end)
+
+ it('should define a custom command: HurlVerbose', function()
+ assert.truthy(vim.fn.exists(':HurlVerbose'))
+ end)
+
+ it('should define a custom command: HurlVeryVerbose', function()
+ assert.truthy(vim.fn.exists(':HurlVeryVerbose'))
+ end)
+
+ it('should define a custom command: HurlSetEnvFile', function()
+ assert.truthy(vim.fn.exists(':HurlSetEnvFile'))
+ end)
+
+ it('should define a custom command: HurlSetVariable', function()
+ assert.truthy(vim.fn.exists(':HurlSetVariable'))
+ end)
+
+ it('should define a custom command: HurlRerun', function()
+ assert.truthy(vim.fn.exists(':HurlRerun'))
+ end)
end)
nd) |
WHAT
New command HurlSelectEnvFile to easy select environment file
WHY
HOW
Screenshots (if appropriate):
Types of changes
Checklist:
Important
Adds
HurlSelectEnvFilecommand tohurl.nvimfor selecting and registering environment files, with updates to configuration and documentation.HurlSelectEnvFilecommand inmain.luato select and register environment files.select_env_file()function inmain.luato prompt user for file selection.default_configininit.luato includeenv_patternfor environment file matching.README.mdanddoc/hurl.nvim.txtto include usage instructions forHurlSelectEnvFile.find_env_files()function inutils.luato locate environment files based onenv_pattern.This description was created by
for 1be249e. You can customize this summary. It will automatically update as commits are pushed.
Summary by CodeRabbit
New Features
Documentation