diff --git a/__tests__/api-writer/glua-api-writer.spec.ts b/__tests__/api-writer/glua-api-writer.spec.ts index 7042bf1..3aba548 100644 --- a/__tests__/api-writer/glua-api-writer.spec.ts +++ b/__tests__/api-writer/glua-api-writer.spec.ts @@ -3,7 +3,9 @@ import { apiDefinition as hookApiDefinition, json as hookJson } from '../test-da // import { apiDefinition as libraryFunctionApiDefinition, json as libraryFunctionJson } from '../test-data/offline-sites/gmod-wiki/library-function-ai-getscheduleid'; import { apiDefinition as structApiDefinition, markup as structMarkup, json as structJson } from '../test-data/offline-sites/gmod-wiki/struct-custom-entity-fields'; // import { apiDefinition as enumApiDefinition, json as enumJson } from '../test-data/offline-sites/gmod-wiki/enums-use'; -import { markup as panelMarkup, structApiDefinition as panelApiDefinition } from '../test-data/offline-sites/gmod-wiki/panel-slider'; +import { markup as panelMarkup, apiDefinition as panelApiDefinition } from '../test-data/offline-sites/gmod-wiki/panel-slider'; +import { markup as multiReturnFuncMarkup, apiDefinition as multiReturnFuncApiDefinition } from '../test-data/offline-sites/gmod-wiki/library-function-concommand-gettable'; +import { markup as varargsFuncMarkup, apiDefinition as varargsFuncApiDefinition } from '../test-data/offline-sites/gmod-wiki/library-function-coroutine-resume'; import { LibraryFunction, WikiPage, WikiPageMarkupScraper } from '../../src/scrapers/wiki-page-markup-scraper'; import { GluaApiWriter } from '../../src/api-writer/glua-api-writer'; import fetchMock from "jest-fetch-mock"; @@ -52,6 +54,38 @@ describe('GLua API Writer', () => { expect(api).toEqual(panelApiDefinition); }); + it('should properly handle multiple return types', async () => { + const writer = new GluaApiWriter(); + + fetchMock.mockResponseOnce(multiReturnFuncMarkup); + + const responseMock = { + url: 'https://wiki.facepunch.com/gmod/concommand.GetTable?format=text', + }; + + const scrapeCallback = new WikiPageMarkupScraper(responseMock.url).getScrapeCallback(); + const panel = await scrapeCallback(responseMock, multiReturnFuncMarkup); + expect(panel).toHaveLength(1); + const api = writer.writePages(panel); + expect(api).toEqual(multiReturnFuncApiDefinition); + }); + + it('should properly handle varargs in parameter and return types', async () => { + const writer = new GluaApiWriter(); + + fetchMock.mockResponseOnce(varargsFuncMarkup); + + const responseMock = { + url: 'https://wiki.facepunch.com/gmod/coroutine.resume?format=text', + }; + + const scrapeCallback = new WikiPageMarkupScraper(responseMock.url).getScrapeCallback(); + const panel = await scrapeCallback(responseMock, varargsFuncMarkup); + expect(panel).toHaveLength(1); + const api = writer.writePages(panel); + expect(api).toEqual(varargsFuncApiDefinition); + }); + it('should write optional parameters with a question mark', () => { const writer = new GluaApiWriter(); // Non-existant page, only to test the optional parameter @@ -80,7 +114,7 @@ describe('GLua API Writer', () => { ], }); - expect(api).toEqual(`---[SHARED] Explodes with an optional intensity.\n---\n---[(View on wiki)](na)\n---@param intensity? number The intensity of the explosion.\n---@return number #The amount of damage done.\nfunction _G.Explode(intensity) end\n\n`); + expect(api).toEqual(`---[SHARED] Explodes with an optional intensity.\n---\n---[(View on wiki)](na)\n---@param intensity? number The intensity of the explosion.\n---@return number # The amount of damage done.\nfunction _G.Explode(intensity) end\n\n`); }); it('should allow overriding specific page addresses', () => { diff --git a/__tests__/test-data/offline-sites/gmod-wiki/library-function-concommand-gettable.ts b/__tests__/test-data/offline-sites/gmod-wiki/library-function-concommand-gettable.ts new file mode 100644 index 0000000..3f051c2 --- /dev/null +++ b/__tests__/test-data/offline-sites/gmod-wiki/library-function-concommand-gettable.ts @@ -0,0 +1,20 @@ +export const markup = ` +Returns the tables of all console command callbacks, and autocomplete functions, that were added to the game with concommand.Add. + +Shared and Menu +lua/includes/modules/concommand.lua + + Table of command callback functions. + Table of command autocomplete functions. + +`; + +export const apiDefinition = +`concommand = {} + +---[SHARED AND MENU] Returns the tables of all console command callbacks, and autocomplete functions, that were added to the game with concommand.Add. +--- +---[(View on wiki)](https://wiki.facepunch.com/gmod/concommand.GetTable) +---@return table # Table of command callback functions. +---@return table # Table of command autocomplete functions. +function concommand.GetTable() end\n\n`; diff --git a/__tests__/test-data/offline-sites/gmod-wiki/library-function-coroutine-resume.ts b/__tests__/test-data/offline-sites/gmod-wiki/library-function-coroutine-resume.ts new file mode 100644 index 0000000..0b4e5b9 --- /dev/null +++ b/__tests__/test-data/offline-sites/gmod-wiki/library-function-coroutine-resume.ts @@ -0,0 +1,24 @@ +export const markup = ` +Resumes the given coroutine and passes the given vararg to either the function arguments or the coroutine.yield that is inside that function and returns whatever yield is called with the next time or by the final return in the function. +Shared and Menu + + Coroutine to resume. + Arguments to be returned by coroutine.yield. + + + If the executed thread code had no errors occur within it. + If an error occurred, this will be a string containing the error message. Otherwise, this will be arguments that were yielded. + +`; + +export const apiDefinition = +`coroutine = {} + +---[SHARED AND MENU] Resumes the given coroutine and passes the given vararg to either the function arguments or the coroutine.yield that is inside that function and returns whatever yield is called with the next time or by the final return in the function. +--- +---[(View on wiki)](https://wiki.facepunch.com/gmod/coroutine.resume) +---@param coroutine thread Coroutine to resume. +---@param ... any Arguments to be returned by coroutine.yield. +---@return boolean # If the executed thread code had no errors occur within it. +---@return any ... # If an error occurred, this will be a string containing the error message. Otherwise, this will be arguments that were yielded. +function coroutine.resume(coroutine, ...) end\n\n`; diff --git a/__tests__/test-data/offline-sites/gmod-wiki/panel-slider.ts b/__tests__/test-data/offline-sites/gmod-wiki/panel-slider.ts index 0674251..5c096fd 100644 --- a/__tests__/test-data/offline-sites/gmod-wiki/panel-slider.ts +++ b/__tests__/test-data/offline-sites/gmod-wiki/panel-slider.ts @@ -36,7 +36,7 @@ end `; -export const structApiDefinition = +export const apiDefinition = `---@deprecated Panel:SetActionFunction and Panel:PostMessage. Use DNumSlider instead. ---@class Slider : Panel local Slider = {}\n\n`; diff --git a/src/api-writer/glua-api-writer.ts b/src/api-writer/glua-api-writer.ts index e1175e5..1018ca3 100644 --- a/src/api-writer/glua-api-writer.ts +++ b/src/api-writer/glua-api-writer.ts @@ -248,7 +248,7 @@ export class GluaApiWriter { private transformType(type: string) { if (type === 'vararg') - return '...'; + return 'any'; return type; } @@ -270,17 +270,17 @@ export class GluaApiWriter { } if (func.returns) { - const returns = `---@return ${func.returns.map(ret => this.transformType(ret.type)).join(', ')}`; - func.returns.forEach(ret => { const description = removeNewlines(ret.description ?? ''); - if (func.returns!.length === 1) { - luaDocComment += `${returns} #${description}\n`; - return; - } + luaDocComment += `---@return `; + + if (ret.type === 'vararg') + luaDocComment += 'any ...'; + else + luaDocComment += `${this.transformType(ret.type)}`; - luaDocComment += `${returns} #${this.transformType(ret.type)} - ${description}\n`; + luaDocComment += ` # ${description}\n`; }); }