Модуль:Diff/testcases

Материал из Википедии — свободной энциклопедии
Перейти к навигации Перейти к поиску
Документация
local suite = require('Модуль:ScribuntoUnit'):new()
local diff = require('Модуль:Diff')

function suite:test_strLongestCommonRange_common_start()
	local d1, d2
	d1, d2 = diff.strLongestCommonRange('1234', '12')
	self:assertDeepEquals({1, 2}, d1)
	self:assertDeepEquals({1, 2}, d2)

	d1, d2 = diff.strLongestCommonRange('12', '1234')
	self:assertDeepEquals({1, 2}, d1)
	self:assertDeepEquals({1, 2}, d2)
end

function suite:test_strLongestCommonRange_common_end()
	local d1, d2
	d1, d2 = diff.strLongestCommonRange('1234', '34')
	self:assertDeepEquals({3, 4}, d1)
	self:assertDeepEquals({1, 2}, d2)

	d1, d2 = diff.strLongestCommonRange('34', '1234')
	self:assertDeepEquals({1, 2}, d1)
	self:assertDeepEquals({3, 4}, d2)
end

function suite:test_strLongestCommonRange_added()
	local d1, d2
	d1, d2 = diff.strLongestCommonRange('Я пишу программу в редакторе.', 'Я пишу программу в хорошем редакторе.')
	self:assertDeepEquals({1, 19}, d1)
	self:assertDeepEquals({1, 19}, d2)

	d1, d2 = diff.strLongestCommonRange('Я пишу программу.', 'Я пишу большую программу.')
	self:assertDeepEquals({7, 17}, d1)
	self:assertDeepEquals({15, 25}, d2)

	d1, d2 = diff.strLongestCommonRange('Я пишу программу в редакторе.', 'Я пишу большую программу в хорошем редакторе.')
	self:assertDeepEquals({7, 19}, d1)
	self:assertDeepEquals({15, 27}, d2)

	d1, d2 = diff.strLongestCommonRange('Я пишу в редакторе.', 'Я пишу программы в редакторе.')
	self:assertDeepEquals({7, 19}, d1)
	self:assertDeepEquals({17, 29}, d2)
end


function suite:test_strLongestCommonRange_removed()
	local d1, d2
	d1, d2 = diff.strLongestCommonRange('Я пишу программу в хорошем редакторе.', 'Я пишу программу в редакторе.')
	self:assertDeepEquals({1, 19}, d1)
	self:assertDeepEquals({1, 19}, d2)

	d1, d2 = diff.strLongestCommonRange('Я пишу большую программу.', 'Я пишу программу.')
	self:assertDeepEquals({15, 25}, d1)
	self:assertDeepEquals({7, 17}, d2)

	d1, d2 = diff.strLongestCommonRange('Я пишу большую программу в хорошем редакторе.', 'Я пишу программу в редакторе.')
	self:assertDeepEquals({15, 27}, d1)
	self:assertDeepEquals({7, 19}, d2)

	d1, d2 = diff.strLongestCommonRange('Я пишу программы в редакторе.', 'Я пишу в редакторе.')
	self:assertDeepEquals({17, 29}, d1)
	self:assertDeepEquals({7, 19}, d2)
end

function suite:test_strLongestCommonRange_empty()
	local d1, d2
	d1, d2 = diff.strLongestCommonRange('', '')
	self:assertDeepEquals(nil, d1)
	self:assertDeepEquals(nil, d2)

	d1, d2 = diff.strLongestCommonRange('', 'def')
	self:assertDeepEquals(nil, d1)
	self:assertDeepEquals(nil, d2)

	d1, d2 = diff.strLongestCommonRange('abc', '')
	self:assertDeepEquals(nil, d1)
	self:assertDeepEquals(nil, d2)
end

function suite:test_strLongestCommonRange_different()
	local d1, d2
	d1, d2 = diff.strLongestCommonRange('abc', 'def')
	self:assertDeepEquals(nil, d1)
	self:assertDeepEquals(nil, d2)

	d1, d2 = diff.strLongestCommonRange('a', 'b')
	self:assertDeepEquals(nil, d1)
	self:assertDeepEquals(nil, d2)
end

function suite:test_strLongestCommonRange_equal()
	local d1, d2
	d1, d2 = diff.strLongestCommonRange('abc', 'abc')
	self:assertDeepEquals({1, 3}, d1)
	self:assertDeepEquals({1, 3}, d2)

	d1, d2 = diff.strLongestCommonRange('a', 'a')
	self:assertDeepEquals({1, 1}, d1)
	self:assertDeepEquals({1, 1}, d2)
end

function suite:test_strLongestCommonRange_singleSymbol()
	local d1, d2
	d1, d2 = diff.strLongestCommonRange('b', 'abc')
	self:assertDeepEquals({1, 1}, d1)
	self:assertDeepEquals({2, 2}, d2)

	d1, d2 = diff.strLongestCommonRange('abc', 'b')
	self:assertDeepEquals({2, 2}, d1)
	self:assertDeepEquals({1, 1}, d2)
end

function suite:test_strLongestCommonRange_longExample()
	local d1, d2
	d1, d2 = diff.strLongestCommonRange(
		'<span class="citation" id="CITEREFCasotti, Lindberg, Braun2000"><i>Casotti&nbsp;G.</i> [https://journals.physiology.org/doi/full/10.1152/ajpregu.2000.279.5.R1722 Functional morphology of the avian medullary cone] :&nbsp;&lsqb;<abbr title="английский язык">англ.</abbr>&rsqb; :&nbsp;&lsqb;[https://web.archive.org/web/20220317045420/https://journals.physiology.org/doi/full/10.1152/ajpregu.2000.279.5.R1722 <abbr title="Архивная копия от указанной даты">арх.</abbr>]&nbsp;17 марта 2022&rsqb; /&nbsp;G. Casotti, K. K. Lindberg, E. J. Braun //&nbsp;American journal of physiology. Regulatory, integrative and comparative physiology<sup class="noprint">[[d:Q2201819|&#91;d&#93;]]</sup>. — 2000. — Vol.&nbsp;279, iss.&nbsp;5. — <span class="nowrap">1 November</span>. — P.&nbsp;R1722—30. — [[Международный стандартный сериальный номер|ISSN]]&nbsp;[https://portal.issn.org/resource/issn/0363-6119 0363-6119], [https://portal.issn.org/resource/issn/1522-1490 1522-1490]. — [[Цифровой идентификатор объекта|doi]]:[https://doi.org/10.1152/AJPREGU.2000.279.5.R1722 10.1152/ajpregu.2000.279.5.r1722]. — [[PMID]]&nbsp;[https://pubmed.ncbi.nlm.nih.gov/11049855 11049855]. — [[Викиданные|WD]]&nbsp;[[d:Q73118986|73118986]].</span>',
		'<span class="citation" id="CITEREFCasotti, Lindberg, Braun2000"><i>Casotti&nbsp;G.</i> [https://journals.physiology.org/doi/full/10.1152/ajpregu.2000.279.5.R1722 Functional morphology of the avian medullary cone] :&nbsp;&lsqb;<abbr title="английский язык">англ.</abbr>&rsqb; :&nbsp;&lsqb;[https://web.archive.org/web/20220317045420/https://journals.physiology.org/doi/full/10.1152/ajpregu.2000.279.5.R1722 <abbr title="Архивная копия от указанной даты">арх.</abbr>]&nbsp;17 марта 2022&rsqb; /&nbsp;G. Casotti, K. K. Lindberg, E. J. Braun //&nbsp;American journal of physiology. Regulatory, integrative and comparative physiology<sup class="noprint">[[d:Q2201819|&#91;d&#93;]]</sup>. — 2000. — Vol.&nbsp;279, iss.&nbsp;5. — <span class="nowrap">1 November</span>. — P.&nbsp;R1722—30. — [[Международный стандартный сериальный номер|ISSN]]&nbsp;[https://portal-plus.issn.org/resource/issn/0363-6119 0363-6119], [https://portal-plus.issn.org/resource/issn/1522-1490 1522-1490]. — [[Цифровой идентификатор объекта|doi]]:[https://doi.org/10.1152/AJPREGU.2000.279.5.R1722 10.1152/ajpregu.2000.279.5.r1722]. — [[PMID]]&nbsp;[https://pubmed.ncbi.nlm.nih.gov/11049855 11049855]. — [[Викиданные|WD]]&nbsp;[[d:Q73118986|Q73118986]].</span>'
	)
	self:assertDeepEquals({1, 857}, d1)
	self:assertDeepEquals({1, 857}, d2)
end

function suite:test_strDiffRanges_empty_str()
	local diffs
	diffs = diff.strDiffRanges(
		'123',
		''
	)
	self:assertDeepEquals({ 
		{ {1, 3}, {1, 0} }
	}, diffs)

	diffs = diff.strDiffRanges(
		'',
		'123'
	)
	self:assertDeepEquals({
		{ {1, 0}, {1, 3} }
	}, diffs)

	diffs = diff.strDiffRanges(
		'',
		''
	)
	self:assertDeepEquals({}, diffs)
end

function suite:test_strDiffRanges_diff_middle()
	local diffs
	diffs = diff.strDiffRanges(
		'1234',
		'134'
	)
	self:assertDeepEquals({ 
		{ {2, 1}, {2, 0} }
	}, diffs)

	diffs = diff.strDiffRanges(
		'13',
		'123'
	)
	self:assertDeepEquals({ 
		{ {2, 0}, {2, 1} }
	}, diffs)

end

function suite:test_strDiffRanges_diff_start()
	local diffs
	diffs = diff.strDiffRanges(
		'1234',
		'34'
	)
	self:assertDeepEquals({ 
		{ {1, 2}, {1, 0} }
	}, diffs)

end

function suite:test_strDiffRanges_diff_end()
	local diffs
	diffs = diff.strDiffRanges(
		'1234',
		'12'
	)
	self:assertDeepEquals({ 
		{ {3, 2}, {3, 0} }
	}, diffs)

	diffs = diff.strDiffRanges(
		'12',
		'1234'
	)
	self:assertDeepEquals({ 
		{ {3, 0}, {3, 2} }
	}, diffs)

end

function suite:test_strDiffRanges_diff_end()
	local diffs
	diffs = diff.strDiffRanges(
		'1234',
		'12'
	)
	self:assertDeepEquals({ 
		{ {3, 2}, {3, 0} }
	}, diffs)

end

function suite:test_fastStrDiffRanges_diff_short_text()
	local diffs
	diffs = diff.fastStrDiffRanges(
		'Simple Hello World!',
		'Not Simple Hello Text!'
	)
	self:assertDeepEquals({ 
		{ {1, 0}, {1, 4} },
		{ {14, 5}, {18, 4} },
	}, diffs)

end

function suite:test_fastStrDiffRanges_diff_long_text()
	local diffs
	diffs = diff.fastStrDiffRanges(
		'It is a very very very very very very very very very long text',
		'It is still a very very very very very very very very very long another text'
	)
	self:assertDeepEquals({ 
		{ {6, 0}, {6, 6} },
		{ {59, 0}, {65, 8} },
	}, diffs)

end

function suite:test_fastStrDiffRanges_diff_no_timeout_512()
	local expected = [[vToV2vTWnmhMhV2K1td+MiuG3HHDokQcsf+n9o6waXsuK7vTQCA99sg95s1TF75ohkx8E7VJKi1qKWDBJ+lrt5ZaoBWd061jd0LbkQJkzuQbMx1zimi2wV4DCyioJWxO
HfPQbLZj4Fg4qYn98q1gM/7UHI//P1N0vKp16MlMM+ixqhi1r67UO+ws+5bk5GpM2g8cCEu0X5sVdYqlXHxkR9D0IFVbSwoFfCuunskjdyDBE9WsUpfDV6VtiNM0j0yT
c6UCKe37spVkcldWJN3vnLGErsnDXOnLjIFY9QSC3zZBc/EsZxcg6qSOi56BcLqsG/fOv+6B8fTvmRxm5vatTTq8FX7wtuWRA2p0Fd5xIlwL86qCs5IzlCvOPVne06Yj
hEvWyXenZtVJ+wvgEL39lH96E0buKy//OleA0Mx+X3tqU/3XTJTUah0KyKUk5xlvIWpWzd6Uh3acGGMb+DRxctx/oWacxHCxbfQZDF7Oh6f9P7sT9yhhszspxI3fFgG7
kjwZXf7aK5c+/PiFzlLQduWXV6QNDBwJgWcByvXktKCx3eKvq37ffHE8da1Wj4xtdAkm9SAVcI9nrcDWOcHTAYPY3WRkG1XRpvPLcmm9ZJF42lGdbY3rcvphrYS3bfWn
HH+JFv11S1bmPRnuXRf3CjFMKLeD7od9zpYP2MV4FFA=]]
	local actual = [[AA7sySsDYXmlrhz1qqBzOMt7KcRwnVqWq0ltt25orO95pUK8qlbcyp/ghLDU+4tXsgsrkBOq2bMUqINapBRKLIDAe55jANDFcUV6wnWDmjQy1r66rrUxq14dbFmrHC/H
DTXF8Xhw6pwNRQG2Pe81TmOQIlMvTIX/7vbxUtOYEdNIxLnGmwtd2Xe2c0Er0Jqj7cSP3GG3BB/1uLwhRdrR+ku1BtPpYRoGk8w9IXB21WarQVSKIuWr9+Bn5zAtl3nW
BH2aXBfVmGNf3aR6qgb0PQs4dZ9yEoHR4bFtD2Pm67vPnyq+uBlekeo8rcyWxJZRdxqpJeNffeitv7YOQtCxLZ3p5numQY9Ib1DC2gMwz0yvUlOdvtlEyhN6fwZnOyZa
JKA3HFhAw8LPBySI8F0xvp9eGdJqHST6KlOfINMX2ygP55wOuhX4PM1qp+vdNAGwiXPuq50K04zQIie8/yF7qiKWtv5EVauhurmjQi9Fn75/mA/i4qIHnbQhB1nikWsx
3T+PqkBlPY/j1Cm1KuTTcym5gtNtN1Jz+YVHSHLE79CtfOteskJTq+dXLC5j2+/nsoqCryjpC9oGnqHhy7fchfSiDsIGaA3sUL4Cr3x/kD1SpBF0phD53uh8yNBEodmY
p11C/SxOu6dBZprDloB6o9L5HK1ps3HEavvGma3Lkc8=]]
	local diffs
	diffs = diff.fastStrDiffRanges(
		expected,
		actual
	)
	self:assertEquals(table.getn(diffs), 1)

	local diff = diffs[1]
	self:assertDeepEquals({
		{ 1, mw.ustring.len(expected) - 1 },
		{ 1, mw.ustring.len(actual) - 1 },
	}, diff)
end

function suite:test_fastStrDiffRanges_diff_no_timeout_4096()
	local diffs
	local expected = [[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]]
	local actual = [[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]]
	diffs = diff.fastStrDiffRanges(
		expected,
		actual
	)
	self:assertEquals(table.getn(diffs), 1)

	local diff = diffs[1]
	self:assertDeepEquals({
		{ 1, mw.ustring.len(expected) - 2 },
		{ 1, mw.ustring.len(actual) - 2 },
	}, diff)
end

function suite:test_strDiffRanges_diff_short_in_long()
	local diffs
	local expected = '<span class="citation">[https://books.google.com/books?id=qbRgCgAAQBAJ Jubb, Kennedy & Palmer\'s Pathology of Domestic Animals] :&nbsp;&lsqb;<abbr title="английский язык">англ.</abbr>&rsqb;. In&nbsp;3 vols. Vol.&nbsp;2 /&nbsp;Ed.: M. Grant Maxie. — Elsevier Health Sciences, 2015. — <span class="nowrap">14 August</span>. — 782&nbsp;p. — [[Международный стандартный книжный номер|ISBN]]&nbsp;[[Служебная:Источники_книг/978-0-7020-5318-4|978-0-7020-5318-4]]. — [[Викиданные|WD]]&nbsp;[[d:Q115676233|Q115676233]].</span>'
	local actual = '<span class="citation">[https://books.google.com/books?id=qbRgCgAAQBAJ Jubb, Kennedy & Palmer\'s Pathology of Domestic Animals] :&nbsp;&lsqb;<abbr title="английский язык">англ.</abbr>&rsqb;. In&nbsp;3 vols. Vol.&nbsp;2 /&nbsp;Ed.: M. G. Maxie. — Elsevier Health Sciences, 2015. — <span class="nowrap">14 August</span>. — 782&nbsp;p. — [[Международный стандартный книжный номер|ISBN]]&nbsp;[[Служебная:Источники_книг/978-0-7020-5318-4|978-0-7020-5318-4]]. — [[Викиданные|WD]]&nbsp;[[d:Q115676233|Q115676233]].</span>'
	diffs = diff.strDiffRanges(
		expected,
		actual
	)
	self:assertTrue(next(diffs) ~= nil)
	local diff = diffs[1]
	local s1 = mw.ustring.sub(expected, diff[1][1], diff[1][1] + diff[1][2] - 1)
	local s2 = mw.ustring.sub(actual, diff[2][1], diff[2][1] + diff[2][2] - 1)
	self:assertEquals('rant / .', s1 .. ' / ' .. s2)
	self:assertEquals(table.getn(diffs), 1)
end

function suite:test_fastStrDiffRanges_diff_short_in_long()
	local diffs
	local expected = '<span class="citation">[https://books.google.com/books?id=qbRgCgAAQBAJ Jubb, Kennedy & Palmer\'s Pathology of Domestic Animals] :&nbsp;&lsqb;<abbr title="английский язык">англ.</abbr>&rsqb;. In&nbsp;3 vols. Vol.&nbsp;2 /&nbsp;Ed.: M. Grant Maxie. — Elsevier Health Sciences, 2015. — <span class="nowrap">14 August</span>. — 782&nbsp;p. — [[Международный стандартный книжный номер|ISBN]]&nbsp;[[Служебная:Источники_книг/978-0-7020-5318-4|978-0-7020-5318-4]]. — [[Викиданные|WD]]&nbsp;[[d:Q115676233|Q115676233]].</span>'
	local actual = '<span class="citation">[https://books.google.com/books?id=qbRgCgAAQBAJ Jubb, Kennedy & Palmer\'s Pathology of Domestic Animals] :&nbsp;&lsqb;<abbr title="английский язык">англ.</abbr>&rsqb;. In&nbsp;3 vols. Vol.&nbsp;2 /&nbsp;Ed.: M. G. Maxie. — Elsevier Health Sciences, 2015. — <span class="nowrap">14 August</span>. — 782&nbsp;p. — [[Международный стандартный книжный номер|ISBN]]&nbsp;[[Служебная:Источники_книг/978-0-7020-5318-4|978-0-7020-5318-4]]. — [[Викиданные|WD]]&nbsp;[[d:Q115676233|Q115676233]].</span>'
	diffs = diff.fastStrDiffRanges(
		expected,
		actual
	)
	self:assertTrue(next(diffs) ~= nil)
	local diff = diffs[1]
	local s1 = mw.ustring.sub(expected, diff[1][1], diff[1][1] + diff[1][2] - 1)
	local s2 = mw.ustring.sub(actual, diff[2][1], diff[2][1] + diff[2][2] - 1)
	self:assertEquals('rant / .', s1 .. ' / ' .. s2)
	self:assertEquals(table.getn(diffs), 1)
end

function suite:test_fastStrDiffRanges_diff_short_in_long_2diffs()
	local expected = '<span class="citation" id="CITEREFCasotti, Lindberg, Braun2000"><i>Casotti&nbsp;G.</i> [https://journals.physiology.org/doi/full/10.1152/ajpregu.2000.279.5.R1722 Functional morphology of the avian medullary cone] :&nbsp;&lsqb;<abbr title="английский язык">англ.</abbr>&rsqb; :&nbsp;&lsqb;[https://web.archive.org/web/20220317045420/https://journals.physiology.org/doi/full/10.1152/ajpregu.2000.279.5.R1722 <abbr title="Архивная копия от указанной даты">арх.</abbr>]&nbsp;17 марта 2022&rsqb; /&nbsp;G. Casotti, K. K. Lindberg, E. J. Braun //&nbsp;American journal of physiology. Regulatory, integrative and comparative physiology<sup class="noprint">[[d:Q2201819|&#91;d&#93;]]</sup>. — 2000. — Vol.&nbsp;279, iss.&nbsp;5. — <span class="nowrap">1 November</span>. — P.&nbsp;R1722—30. — [[Международный стандартный сериальный номер|ISSN]]&nbsp;[https://portal.issn.org/resource/issn/0363-6119 0363-6119], [https://portal.issn.org/resource/issn/1522-1490 1522-1490]. — [[Цифровой идентификатор объекта|doi]]:[https://doi.org/10.1152/AJPREGU.2000.279.5.R1722 10.1152/ajpregu.2000.279.5.r1722]. — [[PMID]]&nbsp;[https://pubmed.ncbi.nlm.nih.gov/11049855 11049855]. — [[Викиданные|WD]]&nbsp;[[d:Q73118986|Q73118986]].</span>'
	local actual = '<span class="citation" id="CITEREFCasotti, Lindberg, Braun2000"><i>Casotti&nbsp;G.</i> [https://journals.physiology.org/doi/full/10.1152/ajpregu.2000.279.5.R1722 Functional morphology of the avian medullary cone] :&nbsp;&lsqb;<abbr title="английский язык">англ.</abbr>&rsqb; :&nbsp;&lsqb;[https://web.archive.org/web/20220317045420/https://journals.physiology.org/doi/full/10.1152/ajpregu.2000.279.5.R1722 <abbr title="Архивная копия от указанной даты">арх.</abbr>]&nbsp;17 марта 2022&rsqb; /&nbsp;G. Casotti, K. K. Lindberg, E. J. Braun //&nbsp;American journal of physiology. Regulatory, integrative and comparative physiology<sup class="noprint">[[d:Q2201819|&#91;d&#93;]]</sup>. — 2000. — Vol.&nbsp;279, iss.&nbsp;5. — <span class="nowrap">1 November</span>. — P.&nbsp;R1722—30. — [[Международный стандартный сериальный номер|ISSN]]&nbsp;[https://portal-plus.issn.org/resource/issn/0363-6119 0363-6119], [https://portal-plus.issn.org/resource/issn/1522-1490 1522-1490]. — [[Цифровой идентификатор объекта|doi]]:[https://doi.org/10.1152/AJPREGU.2000.279.5.R1722 10.1152/ajpregu.2000.279.5.r1722]. — [[PMID]]&nbsp;[https://pubmed.ncbi.nlm.nih.gov/11049855 11049855]. — [[Викиданные|WD]]&nbsp;[[d:Q73118986|Q73118986]].</span>'
	local diffs = diff.fastStrDiffRanges(
		expected,
		actual
	)
	self:assertTrue(next(diffs) ~= nil)

	local diff = diffs[1]
	local s1 = mw.ustring.sub(expected, diff[1][1], diff[1][1] + diff[1][2] - 1)
	local s2 = mw.ustring.sub(actual, diff[2][1], diff[2][1] + diff[2][2] - 1)
	self:assertEquals(' / -plus', s1 .. ' / ' .. s2)

	self:assertEquals(table.getn(diffs), 2)
	diff = diffs[2]
	s1 = mw.ustring.sub(expected, diff[1][1], diff[1][1] + diff[1][2] - 1)
	s2 = mw.ustring.sub(actual, diff[2][1], diff[2][1] + diff[2][2] - 1)
	self:assertEquals(' / -plus', s1 .. ' / ' .. s2)
end

return suite