You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
zeus/tools/lqc/quickcheck.lua

82 lines
2.6 KiB
Lua

--- Module which contains the core of the quickcheck engine.
-- @module lqc.quickcheck
-- @alias lib
local report = require 'lqc.report'
local map = require 'lqc.helpers.map'
local shuffle = pairs
local lib = {
properties = {}, -- list of all properties
numtests = nil, -- Default amount of times a property should be tested
numshrinks = nil, -- Default amount of times a failing property should be shrunk down
failed = false,
}
--- Checks if the quickcheck configuration is initialized
-- @return true if it is initialized; otherwise false.
local function is_initialized()
return lib.numtests ~= nil and lib.numshrinks ~= nil
end
--- Handles the result of a property.
-- @param result table containing information of the property (or nil on success)
-- @see lqc.property_result
local function handle_result(result)
if not result then
return
end -- successful
lib.failed = true
if type(result.property) == 'table' then -- property failed
report.report_failed_property(result.property, result.generated_values, result.shrunk_values)
return
end
-- FSM failed
report.report_failed_fsm(result.description, result.generated_values, result.shrunk_values)
end
--- Configures the amount of iterations and shrinks the check algorithm should perform.
-- @param numtests Default number of tests per property
-- @param numshrinks Default number of shrinks per property
function lib.init(numtests, numshrinks)
lib.numtests = numtests
lib.numshrinks = numshrinks
end
--- Iterates over all properties in a random order and checks if the property
-- holds true for each generated set of inputs. Raises an error if quickcheck
-- engine is not initialized yet.
function lib.check()
if not is_initialized() then
error 'quickcheck.init() has to be called before quickcheck.check()!'
end
for _, prop in shuffle(lib.properties) do
local result = prop:check()
handle_result(result)
end
end
--- Multithreaded version of check(), uses a thread pool in the underlying
-- implementation. Splits up the properties over different threads.
-- @param numthreads Number of the threads to divide the properties over.
function lib.check_mt(numthreads)
local ThreadPool = require 'lqc.threading.thread_pool'
if not is_initialized() then
error 'quickcheck.init() has to be called before quickcheck.check_mt()!'
end
local pool = ThreadPool.new(numthreads)
for _, prop in shuffle(lib.properties) do
pool:schedule(function()
return prop:check()
end)
end
local results = pool:join()
map(results, handle_result)
end
return lib