<?xml version="1.0"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="ru">
	<id>https://bukvica.org/w/index.php?action=history&amp;feed=atom&amp;title=%D0%9C%D0%BE%D0%B4%D1%83%D0%BB%D1%8C%3ATemplateTester</id>
	<title>Модуль:TemplateTester - История изменений</title>
	<link rel="self" type="application/atom+xml" href="https://bukvica.org/w/index.php?action=history&amp;feed=atom&amp;title=%D0%9C%D0%BE%D0%B4%D1%83%D0%BB%D1%8C%3ATemplateTester"/>
	<link rel="alternate" type="text/html" href="https://bukvica.org/w/index.php?title=%D0%9C%D0%BE%D0%B4%D1%83%D0%BB%D1%8C:TemplateTester&amp;action=history"/>
	<updated>2026-04-12T17:21:34Z</updated>
	<subtitle>История изменений этой страницы в вики</subtitle>
	<generator>MediaWiki 1.43.8</generator>
	<entry>
		<id>https://bukvica.org/w/index.php?title=%D0%9C%D0%BE%D0%B4%D1%83%D0%BB%D1%8C:TemplateTester&amp;diff=238729&amp;oldid=prev</id>
		<title>Karaby: 1 версия импортирована</title>
		<link rel="alternate" type="text/html" href="https://bukvica.org/w/index.php?title=%D0%9C%D0%BE%D0%B4%D1%83%D0%BB%D1%8C:TemplateTester&amp;diff=238729&amp;oldid=prev"/>
		<updated>2025-07-27T15:38:11Z</updated>

		<summary type="html">&lt;p&gt;1 версия импортирована&lt;/p&gt;
&lt;table style=&quot;background-color: #fff; color: #202122;&quot; data-mw=&quot;interface&quot;&gt;
				&lt;tr class=&quot;diff-title&quot; lang=&quot;ru&quot;&gt;
				&lt;td colspan=&quot;1&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;← Предыдущая версия&lt;/td&gt;
				&lt;td colspan=&quot;1&quot; style=&quot;background-color: #fff; color: #202122; text-align: center;&quot;&gt;Версия от 15:38, 27 июля 2025&lt;/td&gt;
				&lt;/tr&gt;&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-notice&quot; lang=&quot;ru&quot;&gt;&lt;div class=&quot;mw-diff-empty&quot;&gt;(нет различий)&lt;/div&gt;
&lt;/td&gt;&lt;/tr&gt;&lt;/table&gt;</summary>
		<author><name>Karaby</name></author>
	</entry>
	<entry>
		<id>https://bukvica.org/w/index.php?title=%D0%9C%D0%BE%D0%B4%D1%83%D0%BB%D1%8C:TemplateTester&amp;diff=238728&amp;oldid=prev</id>
		<title>Буквица&gt;D6194c-1cc: Экранирование скобок при обработке диффов (недостающий код)</title>
		<link rel="alternate" type="text/html" href="https://bukvica.org/w/index.php?title=%D0%9C%D0%BE%D0%B4%D1%83%D0%BB%D1%8C:TemplateTester&amp;diff=238728&amp;oldid=prev"/>
		<updated>2024-01-03T10:24:54Z</updated>

		<summary type="html">&lt;p&gt;Экранирование скобок при обработке диффов (недостающий код)&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Новая страница&lt;/b&gt;&lt;/p&gt;&lt;div&gt;require(&amp;#039;strict&amp;#039;)&lt;br /&gt;
&lt;br /&gt;
local p = {}&lt;br /&gt;
&lt;br /&gt;
local NS_MODULE = 828 --: https://www.mediawiki.org/wiki/Extension_default_namespaces&lt;br /&gt;
local moduleNamespace = mw.site.namespaces[NS_MODULE].name&lt;br /&gt;
&lt;br /&gt;
local formatter = require(moduleNamespace .. &amp;#039;:WDFormat&amp;#039;)&lt;br /&gt;
local f = formatter.f&lt;br /&gt;
local diff = require(moduleNamespace .. &amp;#039;:Diff&amp;#039;)&lt;br /&gt;
&lt;br /&gt;
local langObj = mw.language.getContentLanguage()&lt;br /&gt;
&lt;br /&gt;
local i18n = require(moduleNamespace .. &amp;#039;:I18n&amp;#039;)&lt;br /&gt;
&lt;br /&gt;
local l10n = i18n.load()&lt;br /&gt;
&lt;br /&gt;
local function formatSingleDiff(prevText1, prevText2, old, new, nextTextOld, nextTextNew)&lt;br /&gt;
	return &amp;#039;&amp;lt;div class=&amp;quot;diff-deletedline&amp;quot;&amp;gt;&amp;amp;lt; &amp;#039; .. mw.text.nowiki(prevText1) ..&lt;br /&gt;
		&amp;#039;&amp;lt;del class=&amp;quot;diffchange-inline&amp;quot;&amp;gt;&amp;#039; .. mw.text.nowiki(old) .. &amp;#039;&amp;lt;/del&amp;gt;&amp;#039; ..&lt;br /&gt;
		mw.text.nowiki(nextTextOld) .. &amp;#039;&amp;lt;/div&amp;gt;&amp;#039; ..&lt;br /&gt;
		&amp;#039;&amp;lt;div class=&amp;quot;diff-addedline&amp;quot;&amp;gt;&amp;amp;gt; &amp;#039; .. mw.text.nowiki(prevText2) ..&lt;br /&gt;
		&amp;#039;&amp;lt;ins class=&amp;quot;diffchange-inline&amp;quot;&amp;gt;&amp;#039; .. mw.text.nowiki(new) .. &amp;#039;&amp;lt;/ins&amp;gt;&amp;#039; ..&lt;br /&gt;
		mw.text.nowiki(nextTextNew) .. &amp;#039;&amp;lt;/div&amp;gt;&amp;#039;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function findWordStartBound(text, pos)&lt;br /&gt;
	local i = pos - 1&lt;br /&gt;
	while i &amp;gt; 0 do&lt;br /&gt;
		local c = mw.ustring.sub(text, i, i)&lt;br /&gt;
		if mw.ustring.match(c, &amp;quot;[ \t\n&amp;gt;%]]&amp;quot;) then&lt;br /&gt;
			return i + 1&lt;br /&gt;
		end&lt;br /&gt;
		if mw.ustring.match(c, &amp;quot;[%[&amp;lt;]&amp;quot;) then&lt;br /&gt;
			return i&lt;br /&gt;
		end&lt;br /&gt;
		i = i - 1&lt;br /&gt;
	end&lt;br /&gt;
	return 1&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function findWordEndBound(text, pos)&lt;br /&gt;
	local i = pos + 1&lt;br /&gt;
	while i &amp;lt;= mw.ustring.len(text) do&lt;br /&gt;
		local c = mw.ustring.sub(text, i, i)&lt;br /&gt;
		if mw.ustring.match(c, &amp;quot;[ \t\n%[&amp;lt;]&amp;quot;) then&lt;br /&gt;
			return i - 1&lt;br /&gt;
		end&lt;br /&gt;
		if mw.ustring.match(c, &amp;quot;[&amp;gt;%]]&amp;quot;) then&lt;br /&gt;
			return i&lt;br /&gt;
		end&lt;br /&gt;
		i = i + 1&lt;br /&gt;
	end&lt;br /&gt;
	return 1&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function formatDiffs(expected, processed, isPattern)&lt;br /&gt;
	if expected == nil and processed == nil then&lt;br /&gt;
		return &amp;#039;&amp;#039;&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	local diffsStr = &amp;#039;&amp;lt;div class=&amp;quot;diff-in-test&amp;quot;&amp;gt;&amp;#039;&lt;br /&gt;
	if processed == nil then&lt;br /&gt;
		diffsStr = diffsStr .. formatSingleDiff(&amp;#039;&amp;#039;, expected, &amp;#039;&amp;#039;, &amp;#039;&amp;#039;)&lt;br /&gt;
	elseif expected == nil then&lt;br /&gt;
		if isPattern then&lt;br /&gt;
			processed = mw.ustring.gsub(processed, &amp;#039;%%([%%%.%-%[%]%(%)])&amp;#039;, function (s)&lt;br /&gt;
				return s&lt;br /&gt;
			end)&lt;br /&gt;
		end&lt;br /&gt;
		diffsStr = diffsStr .. formatSingleDiff(&amp;#039;&amp;#039;, &amp;#039;&amp;#039;, processed, &amp;#039;&amp;#039;)&lt;br /&gt;
	else&lt;br /&gt;
		local diffs = diff.fastStrDiffRanges(expected, processed)&lt;br /&gt;
		for i, d in ipairs(diffs) do&lt;br /&gt;
			local s1 = &amp;#039;&amp;#039;&lt;br /&gt;
			if d[1][2] &amp;gt; 0 then&lt;br /&gt;
				s1 = mw.ustring.sub(expected, d[1][1], d[1][1] + d[1][2] - 1)&lt;br /&gt;
			end&lt;br /&gt;
			local s2 = &amp;#039;&amp;#039;&lt;br /&gt;
			if d[2][2] &amp;gt; 0 then&lt;br /&gt;
				s2 = mw.ustring.sub(processed, d[2][1], d[2][1] + d[2][2] - 1)&lt;br /&gt;
			end&lt;br /&gt;
			local s1 = &amp;#039;&amp;#039;&lt;br /&gt;
			local s2 = &amp;#039;&amp;#039;&lt;br /&gt;
			local s1End = d[1][1] + d[1][2]&lt;br /&gt;
			local s2End = d[2][1] + d[2][2]&lt;br /&gt;
			s1End = s1End - 1&lt;br /&gt;
			s2End = s2End - 1&lt;br /&gt;
			if d[1][2] &amp;gt; 0 then&lt;br /&gt;
				s1 = mw.ustring.sub(expected, d[1][1], s1End)&lt;br /&gt;
			end&lt;br /&gt;
			if d[2][2] &amp;gt; 0 then&lt;br /&gt;
				s2 = mw.ustring.sub(processed, d[2][1], s2End)&lt;br /&gt;
			end&lt;br /&gt;
			local wordStart1 = findWordStartBound(expected, d[1][1])&lt;br /&gt;
			local wordStart2 = findWordStartBound(processed, d[2][1])&lt;br /&gt;
			local prevText1 = mw.ustring.sub(expected, wordStart1, d[1][1] - 1)&lt;br /&gt;
			local prevText2 = mw.ustring.sub(processed, wordStart2, d[2][1] - 1)&lt;br /&gt;
			local wordEnd1 = findWordEndBound(expected, s1End)&lt;br /&gt;
			local wordEnd2 = findWordEndBound(processed, s2End)&lt;br /&gt;
			local nextText1 = &amp;#039;&amp;#039;&lt;br /&gt;
			if s1End &amp;gt; 0 then&lt;br /&gt;
				nextText1 = mw.ustring.sub(expected, s1End + 1, wordEnd1)&lt;br /&gt;
			end&lt;br /&gt;
			local nextText2 = &amp;#039;&amp;#039;&lt;br /&gt;
			if s2End &amp;gt; 0 then&lt;br /&gt;
				nextText2 = mw.ustring.sub(processed, s2End + 1, wordEnd2)&lt;br /&gt;
			end&lt;br /&gt;
			if isPattern then&lt;br /&gt;
				prevText2 = mw.ustring.gsub(prevText2, &amp;#039;%%([%%%.%-%[%]%(%)])&amp;#039;, function (s)&lt;br /&gt;
					return s&lt;br /&gt;
				end)&lt;br /&gt;
				s2 = mw.ustring.gsub(s2, &amp;#039;%%([%%%.%-%[%]%(%)])&amp;#039;, function (s)&lt;br /&gt;
					return s&lt;br /&gt;
				end)&lt;br /&gt;
				nextText2 = mw.ustring.gsub(nextText2, &amp;#039;%%([%%%.%-%[%]%(%)])&amp;#039;, function (s)&lt;br /&gt;
					return s&lt;br /&gt;
				end)&lt;br /&gt;
			end&lt;br /&gt;
			diffsStr = diffsStr .. formatSingleDiff(prevText1, prevText2, s1, s2, nextText1, nextText2)&lt;br /&gt;
			if i &amp;gt; 4 then&lt;br /&gt;
				break&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
&lt;br /&gt;
	diffsStr = diffsStr .. &amp;#039;&amp;lt;/div&amp;gt;&amp;#039;&lt;br /&gt;
	return diffsStr&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function preprocessTests(frame, tests, failedOnly)&lt;br /&gt;
	local passed = 0&lt;br /&gt;
	for _, test in ipairs(tests) do&lt;br /&gt;
		test.input = test.input&lt;br /&gt;
		test.output = test.output&lt;br /&gt;
		test.actualOutput = frame:preprocess(test.input) or tostring(test.input) or &amp;#039;&amp;#039;&lt;br /&gt;
		if test.pattern then&lt;br /&gt;
			if mw.ustring.find(test.actualOutput, test.pattern) then&lt;br /&gt;
				test.state = true&lt;br /&gt;
			else&lt;br /&gt;
				test.state = false&lt;br /&gt;
			end&lt;br /&gt;
		elseif test.output then&lt;br /&gt;
			test.state = (test.output == test.actualOutput)&lt;br /&gt;
		else&lt;br /&gt;
			test.state = false&lt;br /&gt;
		end&lt;br /&gt;
		test.diff = &amp;#039;&amp;#039;&lt;br /&gt;
		if not test.state then&lt;br /&gt;
			local output = test.pattern or test.output&lt;br /&gt;
			if output then&lt;br /&gt;
				local actualOutput = test.actualOutput&lt;br /&gt;
				if test.pattern and test.diffByPattern then&lt;br /&gt;
					actualOutput = mw.ustring.gsub(actualOutput, &amp;#039;[%%%.%-%[%]]&amp;#039;, function (c)&lt;br /&gt;
						return &amp;#039;%&amp;#039; .. c&lt;br /&gt;
					end)&lt;br /&gt;
				end&lt;br /&gt;
				test.diff = formatDiffs(&lt;br /&gt;
					output,&lt;br /&gt;
					actualOutput,&lt;br /&gt;
					test.diffByPattern&lt;br /&gt;
				)&lt;br /&gt;
			end&lt;br /&gt;
		end&lt;br /&gt;
		if test.state then&lt;br /&gt;
			passed = passed + 1&lt;br /&gt;
		end&lt;br /&gt;
&lt;br /&gt;
		test.visible = true&lt;br /&gt;
		if test.state and failedOnly then&lt;br /&gt;
			test.visible = false&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
	return passed&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function argIsEmpty(s)&lt;br /&gt;
	return (s == nil or s == &amp;#039;&amp;#039;)&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function valueToTable(value)&lt;br /&gt;
	if value == nil then&lt;br /&gt;
		return nil&lt;br /&gt;
	end&lt;br /&gt;
	return { value = value }&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function testsToFormatterTable(tests)&lt;br /&gt;
	for _, test in ipairs(tests) do&lt;br /&gt;
		for key, value in pairs(test) do&lt;br /&gt;
			test[key] = valueToTable(value)&lt;br /&gt;
		end&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local headerTag = {&lt;br /&gt;
	name = &amp;#039;th&amp;#039;,&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
local rowTag = {&lt;br /&gt;
	name = &amp;#039;tr&amp;#039;,&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
local cellTag = {&lt;br /&gt;
	name = &amp;#039;td&amp;#039;,&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
local cellErrorTag = {&lt;br /&gt;
	name = &amp;#039;td&amp;#039;,&lt;br /&gt;
	tag = {&lt;br /&gt;
		name = &amp;#039;span&amp;#039;,&lt;br /&gt;
		classes = { &amp;#039;error&amp;#039; },&lt;br /&gt;
	},&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
local function formatState(source, processedData, result)&lt;br /&gt;
	if source.state.value then&lt;br /&gt;
		result.text = &amp;#039;✅&amp;#039;&lt;br /&gt;
	else &lt;br /&gt;
		result.text = &amp;#039;❌&amp;#039;&lt;br /&gt;
	end&lt;br /&gt;
	result.wikitext = result.text&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function formatSuiteTitle(source, processedData, result)&lt;br /&gt;
	result.text = mw.ustring.format(l10n(&amp;#039;suite-stats&amp;#039;), result.text, source.passed.value, source.total.value)&lt;br /&gt;
	result.wikitext = result.text&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function formatCommentAndWikitext(source, processedData, result)&lt;br /&gt;
	if not source.comment or source.comment.value == &amp;#039;&amp;#039; then&lt;br /&gt;
		result.wikitext = mw.text.nowiki(source.input.value)&lt;br /&gt;
	else&lt;br /&gt;
		local frame = mw.getCurrentFrame()&lt;br /&gt;
		result.text = source.comment.value .. &amp;#039;\n&amp;#039; .. source.input.value&lt;br /&gt;
		result.wikitext = source.comment.value .. &amp;#039;&amp;lt;hr&amp;gt;&amp;#039; .. frame:extensionTag(&amp;#039;syntaxhighlight&amp;#039;, source.input.value, { lang = &amp;#039;wikitext&amp;#039; })&lt;br /&gt;
	end&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function formatNoWiki(source, processedData, result)&lt;br /&gt;
	result.text = mw.text.nowiki(result.text)&lt;br /&gt;
	result.wikitext = result.text&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function filterVisible(source)&lt;br /&gt;
	if not source.visible.value then&lt;br /&gt;
		return false&lt;br /&gt;
	end&lt;br /&gt;
	return true&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local function suiteTitleVisible(source, params)&lt;br /&gt;
	if source.passed.value == source.total.value and params.failedOnly then&lt;br /&gt;
		return false&lt;br /&gt;
	end&lt;br /&gt;
	return true&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
local ResultsProfile = {&lt;br /&gt;
	tag = {&lt;br /&gt;
		name = &amp;#039;div&amp;#039;,&lt;br /&gt;
	},&lt;br /&gt;
	{&lt;br /&gt;
		tag = {&lt;br /&gt;
			name = &amp;#039;table&amp;#039;,&lt;br /&gt;
			classes = { &amp;#039;wikitable&amp;#039; },&lt;br /&gt;
			css = {&lt;br /&gt;
				width = &amp;#039;100 %&amp;#039;,&lt;br /&gt;
			},&lt;br /&gt;
		},&lt;br /&gt;
		{&lt;br /&gt;
			tag = {&lt;br /&gt;
				name = &amp;#039;tr&amp;#039;,&lt;br /&gt;
				tag = {&lt;br /&gt;
					name = &amp;#039;th&amp;#039;,&lt;br /&gt;
					attr = { colspan = 5 },&lt;br /&gt;
				},&lt;br /&gt;
			},&lt;br /&gt;
			cond = suiteTitleVisible,&lt;br /&gt;
			field = &amp;#039;name&amp;#039;,&lt;br /&gt;
			capitalize = true,&lt;br /&gt;
			format = { formatSuiteTitle },&lt;br /&gt;
		},&lt;br /&gt;
		{&lt;br /&gt;
			tag = rowTag,&lt;br /&gt;
			{&lt;br /&gt;
				tag = headerTag,&lt;br /&gt;
				value = &amp;#039;&amp;#039;,&lt;br /&gt;
			},&lt;br /&gt;
			{&lt;br /&gt;
				tag = headerTag,&lt;br /&gt;
				value = l10n(&amp;#039;test&amp;#039;),&lt;br /&gt;
				capitalize = true,&lt;br /&gt;
			},&lt;br /&gt;
			{&lt;br /&gt;
				tag = headerTag,&lt;br /&gt;
				value = l10n(&amp;#039;expected&amp;#039;),&lt;br /&gt;
				capitalize = true,&lt;br /&gt;
			},&lt;br /&gt;
			{&lt;br /&gt;
				tag = headerTag,&lt;br /&gt;
				value = l10n(&amp;#039;actual&amp;#039;),&lt;br /&gt;
				capitalize = true,&lt;br /&gt;
			},&lt;br /&gt;
			{&lt;br /&gt;
				tag = headerTag,&lt;br /&gt;
				value = l10n(&amp;#039;diff&amp;#039;),&lt;br /&gt;
				capitalize = true,&lt;br /&gt;
			},&lt;br /&gt;
			isStatic = true,&lt;br /&gt;
		},&lt;br /&gt;
		{&lt;br /&gt;
			tag = rowTag,&lt;br /&gt;
			cond = filterVisible,&lt;br /&gt;
			field = &amp;#039;tests&amp;#039;,&lt;br /&gt;
			{&lt;br /&gt;
				tag = cellTag,&lt;br /&gt;
				field = &amp;#039;state&amp;#039;,&lt;br /&gt;
				format = { formatState },&lt;br /&gt;
			},&lt;br /&gt;
			{&lt;br /&gt;
				tag = cellTag,&lt;br /&gt;
				field = &amp;#039;input&amp;#039;,&lt;br /&gt;
				format = { formatCommentAndWikitext },&lt;br /&gt;
			},&lt;br /&gt;
			{&lt;br /&gt;
				-- Display error message if wikitext isn&amp;#039;t set&lt;br /&gt;
				conflicts = &amp;#039;input&amp;#039;,&lt;br /&gt;
				tag = cellErrorTag,&lt;br /&gt;
				value = l10n(&amp;#039;error-no-wikitext&amp;#039;),&lt;br /&gt;
			},&lt;br /&gt;
			{&lt;br /&gt;
				conflicts = &amp;#039;pattern&amp;#039;,&lt;br /&gt;
				tag = cellTag,&lt;br /&gt;
				field = &amp;#039;output&amp;#039;,&lt;br /&gt;
			},&lt;br /&gt;
			{&lt;br /&gt;
				conflicts = &amp;#039;output&amp;#039;,&lt;br /&gt;
				tag = cellTag,&lt;br /&gt;
				field = &amp;#039;pattern&amp;#039;,&lt;br /&gt;
			},&lt;br /&gt;
			{&lt;br /&gt;
				-- Display error message if output or&lt;br /&gt;
				-- pattern aren&amp;#039;t set&lt;br /&gt;
				conflicts = { &amp;#039;output&amp;#039;, &amp;#039;pattern&amp;#039; },&lt;br /&gt;
				tag = cellErrorTag,&lt;br /&gt;
				value = l10n(&amp;#039;error-no-expected-or-pattern&amp;#039;),&lt;br /&gt;
			},&lt;br /&gt;
			{&lt;br /&gt;
				tag = cellTag,&lt;br /&gt;
				field = &amp;#039;actualOutput&amp;#039;,&lt;br /&gt;
			},&lt;br /&gt;
			{&lt;br /&gt;
				tag = cellTag,&lt;br /&gt;
				field = &amp;#039;diff&amp;#039;,&lt;br /&gt;
			},&lt;br /&gt;
		},&lt;br /&gt;
	},&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
function p.test(frame)&lt;br /&gt;
	local args = frame.args&lt;br /&gt;
	local failedOnly = not argIsEmpty(args.failedOnly)&lt;br /&gt;
&lt;br /&gt;
	local suites = require(args.testFile)&lt;br /&gt;
	local passed = 0&lt;br /&gt;
	local total = 0&lt;br /&gt;
	for _, suite in ipairs(suites) do&lt;br /&gt;
		suite.passed = preprocessTests(frame, suite.tests, failedOnly)&lt;br /&gt;
		suite.total = table.getn(suite.tests)&lt;br /&gt;
&lt;br /&gt;
		passed = passed + suite.passed&lt;br /&gt;
		total = total + suite.total&lt;br /&gt;
&lt;br /&gt;
		testsToFormatterTable(suite.tests)&lt;br /&gt;
		suite.name = valueToTable(suite.name)&lt;br /&gt;
		suite.passed = valueToTable(suite.passed)&lt;br /&gt;
		suite.total = valueToTable(suite.total)&lt;br /&gt;
	end&lt;br /&gt;
	if passed == total then&lt;br /&gt;
		return mw.ustring.format(l10n(&amp;#039;all-tests-passed&amp;#039;), args.testFile)&lt;br /&gt;
	end&lt;br /&gt;
	&lt;br /&gt;
	local params = {&lt;br /&gt;
		failedOnly = failedOnly,&lt;br /&gt;
	}&lt;br /&gt;
&lt;br /&gt;
	local selfTitle = frame:getTitle()&lt;br /&gt;
	local styles = frame:extensionTag(&amp;#039;templatestyles&amp;#039;, &amp;#039;&amp;#039;, { src = selfTitle .. &amp;#039;/styles.css&amp;#039; })&lt;br /&gt;
	local passedInfo = mw.ustring.format(l10n(&amp;#039;all-tests-stats&amp;#039;), args.testFile, passed, total, total - passed)&lt;br /&gt;
	return styles .. &amp;#039;&amp;lt;div class=&amp;quot;mw-collapsible mw-collapsed&amp;quot;&amp;gt;&amp;#039; .. passedInfo .. &amp;#039;&amp;lt;div class=&amp;quot;mw-collapsible-content&amp;quot; style=&amp;quot;overflow: auto;&amp;quot;&amp;gt;&amp;#039; .. formatter.format(ResultsProfile, suites, nil, params) .. &amp;#039;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;&amp;#039;&lt;br /&gt;
end&lt;br /&gt;
&lt;br /&gt;
return p&lt;/div&gt;</summary>
		<author><name>Буквица&gt;D6194c-1cc</name></author>
	</entry>
</feed>