Edge Rewrite
// HTMLRewriter · presentation

This page was redesigned at the edge.

Cloudflare fetched the original article and streamed it through HTMLRewriter to apply an entirely new visual system without rebuilding the source page.

Jump to content

Module:SMILES2IUPAC/testcases

From Wikipedia, the free encyclopedia
local SMILES2IUPAC =
	require('Module:SMILES2IUPAC')

local p = {}

local tests = {

	-- Alkanes
	{ 'C', 'methane' },
	{ 'CC', 'ethane' },
	{ 'CCC', 'propane' },
	{ 'CCCC', 'butane' },
	{ 'CCCCC', 'pentane' },
	{ 'CCCCCC', 'hexane' },
	{ 'CCCCCCC', 'heptane' },
	{ 'CCCCCCCC', 'octane' },
	{ 'CCCCCCCCC', 'nonane' },
	{ 'CCCCCCCCCC', 'decane' },

	-- Branched alkanes
	{ 'CC(C)C', '2-methylpropane' },
	{ 'CC(C)CC', '2-methylbutane' },
	{ 'CC(C)(C)C', '2,2-dimethylpropane' },
	{ 'CC(C)C(C)C', '2,3-dimethylbutane' },
	{ 'CC(C)CC(C)C', '2,4-dimethylpentane' },
	{ 'CC(C)(C)CC', '2,2-dimethylbutane' },
	{ 'CCC(CC)CC', '3-ethylpentane' },
	{ 'CC(C)C(C)(C)C', '2,2,3-trimethylbutane' },

	-- Alkenes
	{ 'C=C', 'ethene' },
	{ 'CC=C', 'propene' },
	{ 'C=CC', 'propene' },
	{ 'CC=CC', 'but-2-ene' },
	{ 'CC=CCC', 'pent-2-ene' },
	{ 'CCC=CC', 'pent-2-ene' },
	{ 'CC=CCCC', 'hex-2-ene' },
-- Branched alkenes
	{ 'CC=C(C)C', '2-methylbut-2-ene' },
	-- Alcohols
	{ 'CO', 'methanol' },
	{ 'CCO', 'ethanol' },
	{ 'CCCO', 'propan-1-ol' },
	{ 'CC(O)C', 'propan-2-ol' },
	{ 'CCCC(O)C', 'pentan-2-ol' },

	-- Ethers
	{ 'CCOCC', 'ethoxyethane' },

	-- Haloalkanes
	{ 'CCl', 'chloromethane' },
	{ 'CCCl', 'chloroethane' },
	{ 'CCCCl', '1-chloropropane' },
	{ 'CC(Cl)C', '2-chloropropane' },
	{ 'CC(C)Cl', '2-chloropropane' },
	{ 'CC(Cl)CC', '2-chlorobutane' },
	{ 'CC(C)CCl', '1-chloro-2-methylpropane' },
	{ 'CBr', 'bromomethane' },
	{ 'CCBr', 'bromoethane' },
	{ 'CF', 'fluoromethane' },
	{ 'CI', 'iodomethane' },

	-- Mixed functional group
	{ 'CC(O)Cl', '1-chloroethan-1-ol' },

	-- This should NOT be interpreted as an alcohol.
	-- CCOCl = CH3CH2-O-Cl
	{ 'CCOCl', 'ethyl hypochlorite' },

	-- Unsupported
	{ 'C#CC', nil, true },
	{ 'C1CCCCC1', nil, true },
	{ 'C1CCCCC1C', nil, true },
-- Dienes
{ 'C=C=C', 'propadiene' },
{ 'CC=C=C', 'buta-1,2-diene' },
{ 'C=CC=C', 'buta-1,3-diene' },
{ 'CC=CC=C', 'penta-1,3-diene' },
{ 'C=CC=CC', 'penta-1,3-diene' },
{ 'CC=C=CC', 'penta-2,3-diene' },
}

----------------------------------------------------------------------
-- Run one test
----------------------------------------------------------------------

local function run(smiles)

	local ok, name, err = pcall(
		SMILES2IUPAC.nameFromSmiles,
		smiles
	)

	if not ok then
		return nil, tostring(name)
	end

	if not name then
		return nil, err
	end

	return name
end

----------------------------------------------------------------------
-- Test suite
----------------------------------------------------------------------

function p.run()

	local passed = 0
	local failed = 0
	local unsupported = 0

	local rows = {}

	table.insert(rows, '{| class="wikitable sortable"')

	-- Header
	table.insert(
		rows,
		'! # !! SMILES !! Expected !! Got !! Status'
	)

	-- Results
	for i, test in ipairs(tests) do

		local smiles = test[1]
		local expected = test[2]
		local isUnsupported = test[3]

		local actual, err = run(smiles)

		local status
		local got

		--------------------------------------------------------------
		-- Unsupported test
		--------------------------------------------------------------

		if isUnsupported then

			if not actual then

				passed = passed + 1
				unsupported = unsupported + 1

				status =
					'<span style="color: #666; font-weight: bold;">' ..
					'UNSUPPORTED</span>'

				got = 'Unsupported'

			else

				failed = failed + 1

				status =
					'<span style="color: red; font-weight: bold;">' ..
					'FAIL</span>'

				got = actual
			end

		--------------------------------------------------------------
		-- Normal test
		--------------------------------------------------------------

		elseif actual == expected then

			passed = passed + 1

			status =
				'<span style="color: green; font-weight: bold;">' ..
				'PASS</span>'

			got = actual

		--------------------------------------------------------------
		-- Failed normal test
		--------------------------------------------------------------

		else

			failed = failed + 1

			status =
				'<span style="color: red; font-weight: bold;">' ..
				'FAIL</span>'

			if actual then
				got = actual

			elseif err then
				got = 'Error: ' .. tostring(err)

			else
				got = 'nil'
			end
		end

		table.insert(rows, '|-')

		table.insert(
			rows,
			string.format(
				'| %d || <code>%s</code> || %s || %s || %s',
				i,
				smiles,
				tostring(expected or 'Unsupported'),
				tostring(got),
				status
			)
		)
	end

	------------------------------------------------------------------
	-- Summary
	------------------------------------------------------------------

	table.insert(rows, '|-')

	table.insert(
		rows,
		string.format(
			'! colspan="5" style="font-size: 120%%; text-align: center;" | ' ..
			'<span style="color: green; font-weight: bold;">' ..
			'%d / %d Passed' ..
			'</span> &nbsp; ' ..

			'<span style="color: red; font-weight: bold;">' ..
			'%d Failed' ..
			'</span> &nbsp; ' ..

			'<span style="color: #666; font-weight: bold;">' ..
			'%d Unsupported' ..
			'</span>',
			passed,
			#tests,
			failed,
			unsupported
		)
	)

	table.insert(rows, '|}')

	return table.concat(rows, '\n')
end

----------------------------------------------------------------------
-- Test a single SMILES
----------------------------------------------------------------------

function p.test(frame)

	local smiles =
		frame.args[1]
		or frame.args.smiles

	if not smiles or smiles == '' then
		return 'Error: no SMILES supplied'
	end

	local actual, err =
		run(smiles)

	if actual then
		return actual
	end

	return 'Error: ' ..
		tostring(err)
end

return p