Skip to content

Commit

Permalink
Merge pull request #110 from TAServers/102-config-refactor
Browse files Browse the repository at this point in the history
102 - Rewrite configuration handling
  • Loading branch information
Derpius authored Dec 10, 2023
2 parents ce8bce5 + 1d4514e commit 22093e3
Show file tree
Hide file tree
Showing 8 changed files with 165 additions and 77 deletions.
2 changes: 1 addition & 1 deletion package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

15 changes: 15 additions & 0 deletions packages/lest/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,21 @@ The valid change types are:
- `Fixed` for any bug fixes.
- `Security` in case of vulnerabilities.

## [3.0.0] - [#102](https://github.com/TAServers/lest/issues/102)

### Added

- Made it possible to set `testMatch` from the CLI

### Changed

- (**BREAKING**) Changed CLI option format to only support `--option=value` and `-o=value` (`--option` and `-o` are shorthand for `--option=true` and `-o=true` respectively)

### Fixed

- `lest.config.lua` is no longer required to run tests [#97](https://github.com/TAServers/lest/issues/97)
- Unrecognised CLI arguments no longer throw an error, fixing the `--luaCommand` option in the wrapper being unusable [#104](https://github.com/TAServers/lest/issues/104)

## [2.1.0] - [#95](https://github.com/TAServers/lest/issues/95)

### Changed
Expand Down
2 changes: 1 addition & 1 deletion packages/lest/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@taservers/lest",
"version": "2.1.0",
"version": "3.0.0",
"license": "MIT",
"description": "Painless Lua testing.",
"homepage": "https://taservers.github.io/lest/",
Expand Down
68 changes: 0 additions & 68 deletions packages/lest/src/lua/cli.lua

This file was deleted.

12 changes: 12 additions & 0 deletions packages/lest/src/lua/config.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
local ConfigLoader = require("src.lua.utils.configLoader")

return ConfigLoader.new()
:registerProperty("testTimeout", {
type = "number",
default = 5000,
})
:registerProperty("testMatch", {
type = "table",
default = { ".+%.test%.lua" },
})
:load(arg)
9 changes: 2 additions & 7 deletions packages/lest/src/lua/lest.lua
Original file line number Diff line number Diff line change
@@ -1,12 +1,9 @@
require("src.lua.mocking")

local cli = require("src.lua.cli")
local filesInFolder = require("src.lua.utils.filesInFolder")
local runtime = require("src.lua.runtime")
local prettyPrint = require("src.lua.prettyprint")

local options = cli(arg)
local config = dofile(options.config)
local config = require("src.lua.config")

local files = filesInFolder()
local testFiles, testFilesCount = {}, 0
Expand All @@ -21,9 +18,7 @@ for _, filepath in ipairs(files) do
end
end

if options.testTimeout then
runtime.setDefaultTimeout(options.testTimeout)
elseif config.testTimeout then
if config.testTimeout then
runtime.setDefaultTimeout(config.testTimeout)
end

Expand Down
33 changes: 33 additions & 0 deletions packages/lest/src/lua/utils/cliParser.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
local OPTION_PATTERNS = {
"%-%-([%a%-]+)=([^%s]+)",
"%-%-([%a%-]+)",
"%-([%a%-]+)=([^%s]+)",
"%-([%a%-]+)",
}

local function matchOption(arg)
for _, pattern in ipairs(OPTION_PATTERNS) do
local key, value = string.match(arg, pattern)
if key then
return key, value or "true"
end
end
end

--- Parses command line options given as an arg array
---@param args string[]
---@return table<string, string>
local function parseCliOptions(args)
local parsed = {}

for _, arg in ipairs(args) do
local key, value = matchOption(arg)
if key and value then
parsed[key] = value
end
end

return parsed
end

return parseCliOptions
101 changes: 101 additions & 0 deletions packages/lest/src/lua/utils/configLoader.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
local parseCliOptions = require("src.lua.utils.cliParser")

---@class ConfigProperty
---@field default any
---@field type type
---@field cliOnly? boolean

local CLI_ARGUMENT_CASTS_BY_TYPE = {
number = tonumber,
string = function(arg)
return arg
end,
boolean = function(arg)
return arg == "true"
end,
table = function(arg)
local tbl = {}
for match in arg:gmatch("([^,]+)") do
table.insert(tbl, match)
end
return tbl
end,
}

--- Returns the appropriate value for a property given a CLI and config file value
---@param property ConfigProperty
---@param cliValue string?
---@param configFileValue any?
---@return any
local function getPropertyValue(property, cliValue, configFileValue)
if cliValue ~= nil then
local cast = CLI_ARGUMENT_CASTS_BY_TYPE[property.type]
or CLI_ARGUMENT_CASTS_BY_TYPE.string
return cast(cliValue)
end

if configFileValue ~= nil and not property.cliOnly then
return configFileValue
end

return property.default
end

---@class ConfigLoader
---@field properties table<string, ConfigProperty>
local ConfigLoader = {}
ConfigLoader.__index = ConfigLoader

--- Create a new config loader
---@return ConfigLoader
function ConfigLoader.new()
return setmetatable({ properties = {} }, ConfigLoader)
end

--- Registers a new configuration property
---@param name string
---@param options? ConfigProperty
---@return self
function ConfigLoader:registerProperty(name, options)
self.properties[name] = options
return self
end

--- Loads a config with the registered properties
---@param cliArgs string[]
---@return table<string, any>
function ConfigLoader:load(cliArgs)
local cliOptions = parseCliOptions(cliArgs)

local configPath = cliOptions.config or cliOptions.c or "lest.config.lua"
local configLoaded, configFile = pcall(dofile, configPath)
if not configLoaded then
configFile = {}
end

local mergedConfig = {}
for propertyName, property in pairs(self.properties) do
local propertyValue = getPropertyValue(
property,
cliOptions[propertyName],
configFile[propertyName]
)

if type(propertyValue) ~= property.type then
print(
string.format(
"Invalid config: Expected %s to be a %s",
propertyName,
property.type
)
)
os.exit(1)
end

mergedConfig[propertyName] = propertyValue
end

return mergedConfig
end

return ConfigLoader

0 comments on commit 22093e3

Please sign in to comment.