local createLibTest = require('/apis/libtest'); local testlib = createLibTest({ ... }); local PACKAGES_DIR = '/trapos/packages'; local INDEX_PATH = PACKAGES_DIR .. '/index.json'; local function readJson(path) local file = fs.open(path, 'r'); testlib.assertTrue(file, 'missing JSON file: ' .. path); local body = file.readAll(); file.close(); local value = textutils.unserializeJSON(body); testlib.assertTrue(value, 'invalid JSON file: ' .. path); return value; end local function sortedKeys(map) local keys = {}; for key in pairs(map or {}) do keys[#keys + 1] = key; end table.sort(keys); return keys; end local function descriptorPaths() local paths = {}; for _, name in ipairs(fs.list(PACKAGES_DIR)) do local dir = PACKAGES_DIR .. '/' .. name; local path = dir .. '/ccpm.json'; if fs.isDir(dir) and fs.exists(path) then paths[#paths + 1] = { name = name, path = path }; end end table.sort(paths, function(a, b) return a.name < b.name; end); return paths; end local function packageMap() local packages = {}; for _, entry in ipairs(descriptorPaths()) do packages[entry.name] = readJson(entry.path); end return packages; end local function assertSemver(version, label) testlib.assertTrue(type(version) == 'string', label .. ' version must be a string'); testlib.assertTrue(string.match(version, '^%d+%.%d+%.%d+$') ~= nil, label .. ' version must be x.y.z'); end testlib.test('package index matches descriptors', function() local index = readJson(INDEX_PATH); local packages = packageMap(); local indexNames = sortedKeys(index.packages); local descriptorNames = sortedKeys(packages); testlib.assertEquals(#indexNames, #descriptorNames, 'index and descriptor counts differ'); for i, name in ipairs(descriptorNames) do testlib.assertEquals(indexNames[i], name, 'index package names differ'); testlib.assertEquals(index.packages[name], packages[name].version, name .. ' index version differs'); end end); testlib.test('package descriptors are internally consistent', function() local packages = packageMap(); for name, desc in pairs(packages) do testlib.assertEquals(desc.name, name, name .. ' descriptor name differs from directory'); assertSemver(desc.version, name); testlib.assertTrue(type(desc.dependencies) == 'table', name .. ' dependencies must be a table'); testlib.assertTrue(type(desc.files) == 'table', name .. ' files must be a table'); testlib.assertTrue(type(desc.autostart) == 'table', name .. ' autostart must be a table'); if name ~= 'trapos' then testlib.assertTrue(#desc.files > 0, name .. ' must ship at least one file'); end for _, dependency in ipairs(desc.dependencies) do testlib.assertTrue(packages[dependency] ~= nil, name .. ' depends on unknown package ' .. dependency); end local files = {}; for _, filePath in ipairs(desc.files) do files[filePath] = true; testlib.assertTrue(fs.exists('/trapos/' .. filePath), name .. ' missing shipped file ' .. filePath); end for _, autostart in ipairs(desc.autostart) do testlib.assertTrue(files[autostart .. '.lua'], name .. ' autostart not listed in files: ' .. autostart); end end end); testlib.test('root manifest tracks trapos package version', function() local manifest = readJson('/trapos/manifest.json'); local trapos = readJson(PACKAGES_DIR .. '/trapos/ccpm.json'); testlib.assertEquals(manifest.version, trapos.version); end); testlib.run();