Modul:Sandbox/trappist the monk/parameter match test


--[[--------------------------< P A R A M E T E R   M A T C H   T E S T >--------------------------------------

this module is a hack intended to be run from the debug console.  The module assembles and then compares lists
of cs1|2 parameters extracted from the cs1|2 whitelist module and from the cs1|2 configuration module.  In general,
these lists should match.

the module returns one of five tables.  In the debug console the commands are:
	=p.aliases – returns the list of parameters and their associated meta parameter from the ~/Configuration module
	=p.aliases_dups – returns a list of parameters that appear in more than one meta parameter (not necessarily a bad thing depending on the version of the cs1|2 module suite)
	=p.whitelist – returns the list of parameters from the ~/Whitelist module
	=p.alias_params_not_in_whitelist – returns a list of parameters found in the ~/Configuration module but not found in the ~/Whitelist module
	=p.wh_params_not_in_aliases – returns a list of parameters found in the ~/Whitelist module but not found in the ~/Configuration module

set <use_sandboxen> to true to run the above comparisons against the module suite's sandboxen.  if sandboxen don't exist, <use_sandboxen> is ignored

copies of this module are located at:
	da:Modul:Sandkasse/trappist the monk/parameter match test
	en:Module:Sandbox/trappist_the_monk/parameter_match_test
	es:Módulo:Zona de pruebas/trappist_the_monk/parameter_match_test			-- couldn't create there; I don't have permission
	it:Modulo:Sandbox/trappist_the_monk/parameter_match_test
	no:Modul:Sandbox/trappist the monk/parameter match test
	tr:																			-- couldn't create there; I don't have permission?
]]


require('Module:No globals');

local lang_code = mw.language.getContentLanguage():getCode();					-- so that this can be used at multiple wikis
--lang_code = 'TR';																-- for those wikis where I do not have permission to create this module; uppercase to use local copies
local use_sandboxen = false;													-- set to true to evaluate the modules suite's sandboxen

local module;																	-- name of module to be loaded is assembled here

local modules = {
	da = {whitelist = 'Modul:Citation/CS1/Whitelist', configuration = 'Modul:Citation/CS1/Configuration'},
	en = {whitelist = 'Module:Citation/CS1/Whitelist', configuration = 'Module:Citation/CS1/Configuration'},
	es = {whitelist = 'Módulo:Citas/Whitelist', configuration = 'Módulo:Citas/Configuración'},				-- can't create this module at es.wiki; no permission
	it = {whitelist = 'Modulo:Citazione/Whitelist', configuration = 'Modulo:Citazione/Configurazione'},
	nb = {whitelist = 'Modul:Citation/CS1/Whitelist', configuration = 'Modul:Citation/CS1/Configuration'},	-- language code different from interwiki code for no.wiki
	tr = {whitelist = 'Modül:Kaynak/KB1/Beyazliste', configuration = 'Modül:Kaynak/KB1/Yapılandırma'},		-- can't create this module at tr.wiki; no permission?
																											-- local copies for when I can't create this module at xx.wiki
	ES = {whitelist = 'Module:Sandbox/trappist_the_monk/parameter_match_test/Whitelist/es', configuration = 'Module:Sandbox/trappist_the_monk/parameter_match_test/Configuration/es'},
	TR = {whitelist = 'Module:Sandbox/trappist_the_monk/parameter_match_test/Whitelist/tr', configuration = 'Module:Sandbox/trappist_the_monk/parameter_match_test/Configuration/tr'},
	}

local sandboxen = {
	da = '/sandkasse',
	en = '/sandbox',
	es = nil,																	-- apparently '/zona de pruebas' but as of 2021-08-30 only Módulo:Citas/zona de pruebas exists
	it = '/sandbox',
	nb = '/sandkasse',
	tr = nil,																	-- apparently '/deneme' or possibly '/sandbox'; as of 2021-08-30 none exist
	}

local whitelist_m = mw.loadData (table.concat ({modules[lang_code].whitelist, use_sandboxen and sandboxen[lang_code] or ''}));
local whitelist_t = {};															-- a master list of all whitelist parameters

local simple_sections = {
	'basic_arguments',
	'numbered_arguments',
	'limited_basic_arguments',
	'limited_numbered_arguments',
	'arxiv_basic_arguments',
	'biorxiv_basic_arguments',
	'citeseerx_basic_arguments'
	}

local special_sections = {'preprint_arguments', 'unique_arguments'};

local configuration_m = mw.loadData (table.concat ({modules[lang_code].configuration, use_sandboxen and sandboxen[lang_code] or ''}));
local aliases_t = {};															-- a master k/v table of all parameter aliases
local aliases_dups_t = {};														-- a sequence table of parameter aliases that are used in multiple metaparameters

local wh_params_not_in_aliases_t = {};											-- a sequence table of whitelist parameters not found in the master aliases list
local alias_params_not_in_whitelist_t = {};										-- a sequence table of alias list parameters not found in the master whitelist

for _, section in ipairs (simple_sections) do
	if whitelist_m[section] then												-- not all simple sections used in every cs1|2 implementation
		for k, _ in pairs (whitelist_m[section]) do								-- for each of the whitelist tables that do not have subtables
			whitelist_t[k] = section;											-- save the parameter name with section name (just because and all  = true is boring)
		end
	end
end

if whitelist_m[special_sections[1]] or whitelist_m[special_sections[1]] then	-- not all implementations of cs1|2 have these sections
	for _, section in ipairs (special_sections) do
		for k1, v1_t in pairs (whitelist_m[section]) do
			for k, v in pairs (whitelist_m[section][k1]) do
				whitelist_t[k] = table.concat ({section, '[', k1, ']'});		-- save the parameter name with section name (just because and all  = true is boring)
			end
		end
	end
end

for meta, params_t in pairs (configuration_m.aliases) do						-- build a list of all parameters in the ~/Configuration aliases table
	if 'table' == type (params_t) then											-- when only one parameter assigned to <meta>(parameter) it is type string
		for _, param in ipairs (params_t) do									-- loop through the sequence table of parameters associated with <meta> 
			if aliases_t[param] then											-- if already in <aliases_t>
				table.insert (aliases_dups_t, table.concat ({'\'', param, '\' in: \'', meta, '\' duplicated in: \'', aliases_t[param], '\''}));	-- make a note
			else
				aliases_t[param] = meta;										-- add this <param> with its associated <meta> to <aliases_t>
			end
			
			if param:find ('#', 1, true) then									-- if this is an enumerated parameter
				param = param:gsub ('#', '');									-- make a parameter without enumeration
				if aliases_t[param] then										-- if already in <aliases_t>
					if meta ~= aliases_t[param] then
						table.insert (aliases_dups_t, table.concat ({'\'', param, '\',  in: \'', meta, '\' duplicated in: \'', aliases_t[param], '\' (enumneration)'}));	-- make a note
					end
				else
					aliases_t[param] = meta;									-- add this <param> with its associated <meta> to <aliases_t>
				end
			end	
		end

	elseif 'string' == type (params_t) then										-- here when <params_t> is a string
		local param = params_t;
		if aliases_t[param] then												-- if already in <aliases_t>
			table.insert (aliases_dups_t, table.concat ({'\'', param, '\' in: \'', meta, '\' duplicated in: \'', aliases_t[param], '\''}));	-- make a note
		else
			aliases_t[param] = meta;											-- add this <param> with its associated <meta> to <aliases_t>
		end

	elseif 'number' == type (params_t) then										-- here when <params_t> is a number
		local param = params_t;
		param = table.concat ({'error: alias ', tostring (param), ' in metaparameter: ', meta, ' is not a string or table'});
		aliases_t[param] = meta;												-- add this <param> with its error message to <aliases_t>
	end
end

for id, v_t in pairs (configuration_m.id_handlers) do
	for k, param in ipairs (v_t.parameters) do
		if aliases_t[param] then												-- if already in <aliases_t>
			table.insert (aliases_dups_t, table.concat ({param, ' in: id_handlers[', id, '].parameters', ' duplicated in: ', aliases_t[param]}));	-- make a note
		else
			aliases_t[param] = table.concat ({'id_handlers[', id, '].parameters'});	-- add this <param> with its associated id_hamdler to <aliases_t>
		end
	end

	local param = v_t.custom_access;
	if param and aliases_t[param] then											-- if already in <aliases_t>
		table.insert (aliases_dups_t, table.concat ({param, ' in: id_handlers.', 'custom_access', ' duplicated in: ', aliases_t[param]}));	-- make a note
	elseif param then
		aliases_t[param] = table.concat ({'id_handlers.', 'custom_access'});	-- add this <param> with its associated id_hamdler to <aliases_t>
	end
end

for wl_param, _ in pairs (whitelist_t) do
	if not aliases_t[wl_param] then
		table.insert (wh_params_not_in_aliases_t, wl_param);
	end
end

for alias, meta in pairs (aliases_t) do
	if not whitelist_t[alias] then
		table.insert (alias_params_not_in_whitelist_t, table.concat ({alias, ' (', meta, ')'}));
	end
end

table.sort (wh_params_not_in_aliases_t);										-- sort so the lists are more pretty-like
table.sort (alias_params_not_in_whitelist_t);
table.sort (aliases_dups_t);

table.insert (wh_params_not_in_aliases_t, 1,									-- insert headers to describe the lists
	table.concat ({
		'~/Whitelist',
		use_sandboxen and sandboxen[lang_code] or '',
		' parameters not found in ~/Configuration',
		use_sandboxen and sandboxen[lang_code] or ''
		, ' aliases list:'
		}));
table.insert (alias_params_not_in_whitelist_t, 1,
	table.concat ({
		'~/Configuration',
		use_sandboxen and sandboxen[lang_code] or '',
		' alias parameters not found in ~/Whitelist',
		use_sandboxen and sandboxen[lang_code] or '',
		':'
		}));
table.insert (aliases_dups_t, 1,
	table.concat({
		'parameters found in multiple ~/Configuration',
		use_sandboxen and sandboxen[lang_code] or '',
		' metaparameters:'
		}));

local aliases = mw.dumpObject (aliases_t);
local aliases_dups = table.concat (aliases_dups_t, '\n\t');
local wh_params_not_in_aliases = table.concat (wh_params_not_in_aliases_t, '\n\t');
local whitelist = mw.dumpObject (whitelist_t);
local alias_params_not_in_whitelist = table.concat (alias_params_not_in_whitelist_t, '\n\t');

return {
	aliases = aliases,
	aliases_dups = aliases_dups,
	whitelist = whitelist,
	alias_params_not_in_whitelist = alias_params_not_in_whitelist,
	wh_params_not_in_aliases = wh_params_not_in_aliases,
	}