From 315c6248afbf9e5b85c06519e01ad5f9cc61dfd0 Mon Sep 17 00:00:00 2001 From: BoltlessEngineer Date: Mon, 19 Aug 2024 22:51:18 +0900 Subject: [PATCH] test: organize test cases --- lua/rest-nvim/parser/init.lua | 50 ++-- spec/api_spec.lua | 235 --------------- spec/client/curl/command_spec.lua | 1 + spec/{ => examples}/examples_spec.lua | 36 +++ spec/examples/script/pre_request_script.http | 4 + .../variables/in_place_variables.http | 21 ++ spec/parser/http_parser_spec.lua | 276 +++++++++++++++--- spec/script_spec.lua | 19 ++ spec/utils_spec.lua | 38 ++- 9 files changed, 386 insertions(+), 294 deletions(-) delete mode 100644 spec/api_spec.lua rename spec/{ => examples}/examples_spec.lua (54%) create mode 100644 spec/examples/variables/in_place_variables.http diff --git a/lua/rest-nvim/parser/init.lua b/lua/rest-nvim/parser/init.lua index 6af977f..938509b 100644 --- a/lua/rest-nvim/parser/init.lua +++ b/lua/rest-nvim/parser/init.lua @@ -23,12 +23,18 @@ local NAMED_REQUEST_QUERY = vim.treesitter.query.parse("http", [[ request: (_)) @request (section (comment - name: (_) @keyword + name: (_) @_keyword value: (_) @name - (#eq? @keyword "name")) + (#eq? @_keyword "name")) request: (_)) @request ]]) +local IN_PLACE_VARIABLE_QUERY = vim.treesitter.query.parse("http", [[ +(section + !request + (variable_declaration)+ @inplace_variable) +]]) + ---@param node TSNode ---@param field string ---@param source Source @@ -96,7 +102,7 @@ local function parse_urlencoded_form(str) return vim.iter(query_pairs):map(function (query) local key, value = query:match("([^=]+)=?(.*)") if not key then - -- TODO: error + logger.error(("Error while parsing query '%s' from urlencoded form '%s'"):format(query_pairs, str)) return nil end return vim.trim(key) .. "=" .. vim.trim(value) @@ -147,13 +153,12 @@ function parser.parse_body(content_type, body_node, source, context) return nil end elseif node_type == "raw_body" then - -- TODO: exclude comments from text local text = vim.treesitter.get_node_text(body_node, source) if content_type and vim.startswith(content_type, "application/x-www-form-urlencoded") then body.__TYPE = "raw" body.data = parse_urlencoded_form(text) if not body.data then - -- TODO: parsing urlencoded form failed + logger.error("Error while parsing urlencoded form") return nil end else @@ -170,16 +175,13 @@ function parser.parse_body(content_type, body_node, source, context) return body end -local IN_PLACE_VARIABLE_QUERY = "(variable_declaration) @inplace_variable" - ---parse all in-place variables from source ---@param source Source ---@return rest.Context ctx function parser.create_context(source) - local query = vim.treesitter.query.parse("http", IN_PLACE_VARIABLE_QUERY) + local query = IN_PLACE_VARIABLE_QUERY local ctx = Context:new() local _, tree = utils.ts_parse_source(source) - -- TODO: capture variable_decalarations in section without request for _, node in query:iter_captures(tree:root(), source) do if node:type() == "variable_declaration" then parser.parse_variable_declaration(node, source, ctx) @@ -213,7 +215,7 @@ function parser.get_all_request_nodes(source) local _, tree = utils.ts_parse_source(source) local result = {} for node, _ in tree:root():iter_children() do - if node:type() == "section" then + if node:type() == "section" and #node:field("request") > 0 then table.insert(result, node) end end @@ -327,28 +329,34 @@ function parser.parse(node, source, ctx) logger.info("no method provided, falling back to 'GET'") method = "GET" end - local url = expand_variables( - assert(get_node_field_text(req_node, "url", source)), - ctx, - utils.escape - ) - url = url:gsub("\n%s+", "") + -- NOTE: url will be parsed after because in-place variables should be parsed + -- first + local url local name local handlers = {} for child, _ in node:iter_children() do - local node_type = child:type() - if node_type == "pre_request_script" then + local child_type = child:type() + if child_type == "request" then + url = expand_variables( + assert(get_node_field_text(req_node, "url", source)), + ctx, + utils.escape + ) + url = url:gsub("\n%s+", "") + elseif child_type == "pre_request_script" then parser.parse_pre_request_script(child, source, ctx) - elseif node_type == "res_handler_script" then + elseif child_type == "res_handler_script" then local handler = parser.parse_request_handler(child, source, ctx) if handler then table.insert(handlers, handler) end - elseif node_type == "request_separator" then + elseif child_type == "request_separator" then name = get_node_field_text(child, "value", source) - elseif node_type == "comment" and get_node_field_text(child, "name", source) == "name" then + elseif child_type == "comment" and get_node_field_text(child, "name", source) == "name" then name = get_node_field_text(child, "value", source) or name + elseif child_type == "variable_declaration" then + parser.parse_variable_declaration(child, source, ctx) end end if not name then diff --git a/spec/api_spec.lua b/spec/api_spec.lua deleted file mode 100644 index b0ceb98..0000000 --- a/spec/api_spec.lua +++ /dev/null @@ -1,235 +0,0 @@ ----@module 'luassert' - -require("spec.minimum_init") - -local parser = require("rest-nvim.parser") -local utils = require("rest-nvim.utils") -local context = require("rest-nvim.context").Context -local logger = require("rest-nvim.logger") - -local spy = require("luassert.spy") - -local function open(path) - vim.cmd.edit(path) - vim.cmd.source("ftplugin/http.lua") - return 0 -end - ----@diagnostic disable-next-line: duplicate-set-field -vim.notify = function () end - -describe("parser", function() - it("validate http parser", function() - assert.same("http", vim.treesitter.language.get_lang("http")) - end) - it("parse from http string", function() - local source="GET https://github.com\n" - local _, tree = utils.ts_parse_source(source) - local req_node = assert(tree:root():child(0)) - assert.same({ - method = "GET", - url = "https://github.com", - headers = {}, - cookies = {}, - handlers = {}, - }, parser.parse(req_node, source)) - end) - it("parse from http file", function() - local source = open "spec/examples/basic_get.http" - local _, tree = utils.ts_parse_source(source) - local req_node = assert(tree:root():child(0)) - assert.same({ - name = "basic_get#1", - method = "GET", - url = "https://api.github.com/users/boltlessengineer", - headers = { - ["user-agent"] = { "neovim" } - }, - cookies = {}, - handlers = {}, - }, parser.parse(req_node, source)) - end) - it("parse json", function () - local source = "POST https://example.com\n\n{\n\t\"blah\": 1}\n" - local _, tree = utils.ts_parse_source(source) - local req_node = assert(tree:root():child(0)) - assert.same({ - method = "POST", - url = "https://example.com", - headers = {}, - cookies = {}, - handlers = {}, - body = { - __TYPE = "json", - data = "{\n\t\"blah\": 1}" - }, - }, parser.parse(req_node, source)) - end) - it("parse invalid json", function () - local source = "POST https://example.com\n\n{\n\t\"blah\": 1\n" - local _, tree = utils.ts_parse_source(source) - local req_node = assert(tree:root():child(0)) - local spy_log_warn = spy.on(logger, "warn") - parser.parse(req_node, source) - ---@diagnostic disable-next-line: undefined-field - assert.spy(spy_log_warn).called_with("invalid json: '{\n\t\"blah\": 1'") - end) - it("parse xml", function () - local source = [[POST https://example.com - - - - login - password - -]] - local _, tree = utils.ts_parse_source(source) - local req_node = assert(tree:root():child(0)) - assert.same({ - method = "POST", - url = "https://example.com", - headers = {}, - cookies = {}, - handlers = {}, - body = { - __TYPE = "xml", - data = [[ - - login - password -]], - }, - }, parser.parse(req_node, source)) - end) - it("parse invalid xml", function () - logger.info("hi") - local source = "POST https://example.com\n\n + + login + password + +]] + local _, tree = utils.ts_parse_source(source) + local req_node = assert(tree:root():child(0)) + assert.same({ + method = "POST", + url = "https://example.com", + headers = {}, + cookies = {}, + handlers = {}, + body = { + __TYPE = "xml", + data = [[ + + login + password +]], + }, + }, parser.parse(req_node, source)) + end) + it("parse invalid xml", function() + logger.info("hi") + local source = "POST https://example.com\n\n