Modul:Wikidata/Sorters/testcases

Z Wikipedie, otevřené encyklopedie
local builder = require 'Modul:Wikidata/build'
local ScribuntoUnit = require 'Modul:ScribuntoUnit'
local suite = ScribuntoUnit:new()

local simpleCompare = (require 'Modul:Wikidata/lib').simpleCompare

function suite:testSortStatements()
	local provider = {
		{
			invert = false,
			statements = { 2, 1, 4, 3 },
			expected = { 1, 2, 3, 4 },
		},
		{
			invert = true,
			statements = { 2, 1, 2, 3 },
			expected = { 3, 2, 2, 1 },
		},
		{
			invert = false,
			statements = { 2, 'incomplete', 1, 3 },
			expected = { 1, 2, 3, 'incomplete' },
		},
		{
			invert = false,
			statements = { 2, 'incomplete', 'incomplete', 1, 3 },
			expected = { 1, 2, 3, 'incomplete', 'incomplete' },
		},
		{
			invert = true,
			statements = { 2, 'incomplete', 1, 3 },
			expected = { 3, 2, 1, 'incomplete' },
		},
	}
	local myModule = require 'Modul:Wikidata/Sorters'
	myModule.Sorters.xxx = {
		isCompleteStatement = function(st)
			return st ~= 'incomplete'
		end,
		mayCompareStatement = function(st)
			return true
		end,
		compareStatements = simpleCompare
	}
	for _, data in ipairs(provider) do
		local statements = data.statements
		myModule.sortStatements(statements, { sort = { 'xxx' }, invert = data.invert })
		self:assertDeepEquals(data.expected, statements)
	end
end

function suite:testSortStatementsMultipleSorters()
	local provider = {
		{
			invert = false,
			statements = {
				{ 2, 0 },
				{ 1, 0 },
				{ 2, 1 },
				{ 1, 1 },
			},
			expected = {
				{ 1, 0 },
				{ 1, 1 },
				{ 2, 0 },
				{ 2, 1 }
			},
		},
		{
			invert = true,
			statements = {
				{ 2, 0 },
				{ 1, 0 },
				{ 2, 1 },
				{ 1, 1 },
			},
			expected = {
				{ 2, 1 },
				{ 2, 0 },
				{ 1, 1 },
				{ 1, 0 }
			},
		},
		{
			invert = false,
			statements = {
				{ 2, 0 },
				{ 1, 0 },
				{ 'incomplete', 2 },
				{ 1, 1 },
			},
			expected = {
				{ 1, 0 },
				{ 1, 1 },
				{ 2, 0 },
				{ 'incomplete', 2 }
			},
		},
		{
			invert = true,
			statements = {
				{ 2, 0 },
				{ 1, 0 },
				{ 'incomplete', 2 },
				{ 1, 1 },
			},
			expected = {
				{ 2, 0 },
				{ 1, 1 },
				{ 1, 0 },
				{ 'incomplete', 2 }
			},
		},
		{
			invert = false,
			statements = {
				{ 1, 1 },
				{ 1, 'incomplete' },
				{ 'incomplete', 'incomplete' },
				{ 1, 0 },
				{ 'incomplete', 2 },
				{ 'incomplete', 0 },
			},
			expected = {
				{ 1, 0 },
				{ 1, 1 },
				{ 1, 'incomplete' },
				{ 'incomplete', 0 },
				{ 'incomplete', 2 },
				{ 'incomplete', 'incomplete' }
			},
		},
	}
	local myModule = require 'Modul:Wikidata/Sorters'
	myModule.Sorters.xxx = {
		isCompleteStatement = function(st)
			return st[1] ~= 'incomplete'
		end,
		mayCompareStatement = function(st)
			return true
		end,
		compareStatements = function(first, second)
			return simpleCompare(first[1], second[1])
		end
	}
	myModule.Sorters.yyy = {
		isCompleteStatement = function(st)
			return st[2] ~= 'incomplete'
		end,
		mayCompareStatement = function(st)
			return true
		end,
		compareStatements = function(first, second)
			return simpleCompare(first[2], second[2])
		end
	}
	for _, data in ipairs(provider) do
		local statements = data.statements
		myModule.sortStatements(statements, { sort = { 'xxx', 'yyy' }, invert = data.invert })
		self:assertDeepEquals(data.expected, statements)
	end
end

function suite:testSortStatementsDefaultSorter()
	local provider = {
		{
			datatype = 'string',
			expected = 'alpha',
			values = { 'a', 'b' }
		},
		{
			datatype = 'monolingualtext',
			expected = 'alpha',
			values = { 'a', 'b' }
		},
		{
			datatype = 'time',
			expected = 'time',
			values = { '1999', '2000' }
		},
		{
			datatype = 'quantity',
			expected = 'number',
			values = { 1, 2 }
		}
	}
	local myModule = require 'Modul:Wikidata/Sorters'
	for _, data in ipairs(provider) do
		local called = false
		myModule.Sorters[data.expected] = {
			isCompleteStatement = function(st)
				return true
			end,
			mayCompareStatement = function(st)
				return true
			end,
			compareStatements = function(first, second)
				called = true
				return simpleCompare(first.sortBy, second.sortBy)
			end
		}
		local statements = {}
		for _, value in ipairs(data.values) do
			local statement = builder.buildStatement{
				datatype = data.datatype,
				value = value
			}
			statement.sortBy = value
			table.insert(statements, statement)
		end
		myModule.sortStatements(statements, { sort = { 'default' } })
		self:assertTrue(called)
	end
end

local function buildStatementWithQualifiers(prop, datatype, values)
	local statement = {}
	for _, value in ipairs(values) do
		if value then
			if not statement.qualifiers then
				statement.qualifiers = {
					[prop] = {}
				}
				statement.value = value
			end
			local snak = builder.buildSnak{
				datatype = datatype,
				value = value
			}
			snak.value = value
			table.insert(statement.qualifiers[prop], snak)
		end
	end
	return statement
end

function suite:testSortStatementsByQualifier()
	local provider = {
		{
			qualifier = 'P1',
			datatype = 'quantity',
			expected = 'number',
			values = { 2, 3, 1 },
			ordered = { 1, 2, 3 }
		},
		{
			qualifier = 'P2',
			datatype = 'string',
			expected = 'alpha',
			values = { 'c', false, 'a' },
			ordered = { 'a', 'c', false }
		},
	}
	local myModule = require 'Modul:Wikidata/Sorters'
	for _, data in ipairs(provider) do
		local called = false
		myModule.Sorters[data.expected] = {
			mayCompareSnak = function()
				return true
			end,
			isCompleteSnak = function()
				return true
			end,
			compareSnaks = function(first, second)
				called = true
				return simpleCompare(first.value, second.value)
			end
		}
		local statements = {}
		for _, value in ipairs(data.values) do
			table.insert(statements, buildStatementWithQualifiers(data.qualifier, data.datatype, { value }))
		end
		local expected = {}
		for _, value in ipairs(data.ordered) do
			table.insert(expected, buildStatementWithQualifiers(data.qualifier, data.datatype, { value }))
		end
		myModule.sortStatements(statements, { sort = { data.qualifier } })
		self:assertTrue(called)
		self:assertDeepEquals(expected, statements)
	end
end

function suite:testSortStatementsByQualifierHavingMultipleValues()
	local provider = {
		{
			qualifier = 'P1',
			datatype = 'quantity',
			expected = 'number',
			values = {
				{ 2, 3 },
				{ 3, 4 },
				{ 1, 1 }
			},
			ordered = {
				{ 1, 1 },
				{ 2, 3 },
				{ 3, 4 }
			}
		},
		{
			qualifier = 'P2',
			datatype = 'string',
			expected = 'alpha',
			values = {
				{ 'b', 'c' },
				{},
				{ 'c' },
				{ 'a' }
			},
			ordered = {
				{ 'a' },
				{ 'b', 'c' },
				{ 'c' },
				{}
			}
		},
	}
	local myModule = require 'Modul:Wikidata/Sorters'
	for _, data in ipairs(provider) do
		local called = false
		myModule.Sorters[data.expected] = {
			mayCompareSnak = function()
				return true
			end,
			isCompleteSnak = function()
				return true
			end,
			compareSnaks = function(first, second)
				called = true
				return simpleCompare(first.value, second.value)
			end
		}
		local statements = {}
		for _, values in ipairs(data.values) do
			table.insert(statements, buildStatementWithQualifiers(data.qualifier, data.datatype, values))
		end
		local expected = {}
		for _, values in ipairs(data.ordered) do
			table.insert(expected, buildStatementWithQualifiers(data.qualifier, data.datatype, values))
		end
		myModule.sortStatements(statements, { sort = { data.qualifier } })
		self:assertTrue(called)
		self:assertDeepEquals(expected, statements)
	end
end

function suite:testSortQualifiers()
	self:assertTrue(false)
end
--[[
local function buildStatementFromSnaktype(snaktype, rank)
	return builder.buildStatement{
		datatype = 'wikibase-item',
		snaktype = snaktype,
		rank = rank
	}
end

local function buildStatementFromEntityId(entityId, rank)
	return builder.buildStatement{
		datatype = 'wikibase-item',
		rank = rank,
		value = entityId
	}
end

function suite:testSortByDatePoint()
	local statements, expected = {}, {}
	for _, date in ipairs({ '2001', false, '2002', false, '2000', '2003' }) do
		local statement = buildStatementFromEntityId(2)
		if date then
			statement.qualifiers = {
				P585 = {
					builder.buildSnak{ datatype = 'time', value = date }
				}
			}
		end
		table.insert(statements, statement)
	end
	for _, date in ipairs({ '2000', '2001', '2002', '2003', false, false }) do
		local statement = buildStatementFromEntityId(2)
		if date then
			statement.qualifiers = {
				P585 = {
					builder.buildSnak{ datatype = 'time', value = date }
				}
			}
		end
		table.insert(expected, statement)
	end
	myModule.sortStatements(statements, { sort = 'date' })
	self:assertDeepEquals(expected, statements)
end

function suite:testSortByDateRangeStart()
	local statements, expected = {}, {}
	for _, start in ipairs({ '2002', false, '2001', '2003', false, '2000' }) do
		local statement = buildStatementFromEntityId(5)
		if start then
			statement.qualifiers = {
				P580 = {
					builder.buildSnak{ datatype = 'time', value = start }
				}
			}
		end
		table.insert(statements, statement)
	end
	for _, start in ipairs({ '2000', '2001', '2002', '2003', false, false }) do
		local statement = buildStatementFromEntityId(5)
		if start then
			statement.qualifiers = {
				P580 = {
					builder.buildSnak{ datatype = 'time', value = start }
				}
			}
		end
		table.insert(expected, statement)
	end
	myModule.sortStatements(statements, { sort = 'date' })
	self:assertDeepEquals(expected, statements)
end

function suite:testSortByDateRangeEnd()
	local statements, expected = {}, {}
	for _, ending in ipairs({ '2002', false, '2001', '2003', false, '2000' }) do
		local statement = buildStatementFromEntityId(5)
		if ending then
			statement.qualifiers = {
				P582 = {
					builder.buildSnak{ datatype = 'time', value = ending }
				}
			}
		end
		table.insert(statements, statement)
	end
	for _, ending in ipairs({ '2000', '2001', '2002', '2003', false, false }) do
		local statement = buildStatementFromEntityId(5)
		if ending then
			statement.qualifiers = {
				P582 = {
					builder.buildSnak{ datatype = 'time', value = ending }
				}
			}
		end
		table.insert(expected, statement)
	end
	myModule.sortStatements(statements, { sort = 'date' })
	self:assertDeepEquals(expected, statements)
end

function suite:testSortByDateRangeMixed()
	local statements, expected = {}, {}
	for _, range in ipairs({ '2002-', false, '2001-2005', '2002-2004', '-2003', false, '-2000', '2004-', '-2002' }) do
		local statement = buildStatementFromEntityId(5)
		if range then
			local parts = mw.text.split( range, '-' )
			statement.qualifiers = {}
			if parts[1] ~= '' then
				statement.qualifiers.P580 = {
					builder.buildSnak{ datatype = 'time', value = parts[1] }
				}
			end
			if parts[2] ~= '' then
				statement.qualifiers.P582 = {
					builder.buildSnak{ datatype = 'time', value = parts[2] }
				}
			end
		end
		table.insert(statements, statement)
	end
	for _, range in ipairs({ '-2000', '2001-2005', '-2002', '2002-2004', '2002-', '-2003', '2004-', false, false }) do
		local statement = buildStatementFromEntityId(5)
		if range then
			local parts = mw.text.split( range, '-' )
			statement.qualifiers = {}
			if parts[1] ~= '' then
				statement.qualifiers.P580 = {
					builder.buildSnak{ datatype = 'time', value = parts[1] }
				}
			end
			if parts[2] ~= '' then
				statement.qualifiers.P582 = {
					builder.buildSnak{ datatype = 'time', value = parts[2] }
				}
			end
		end
		table.insert(expected, statement)
	end
	myModule.sortStatements(statements, { sort = 'date' })
	self:assertDeepEquals(expected, statements)
end

function suite:testSortByRank()
	local statements, expected = {}, {}
	for _, rank in ipairs({ 'deprecated', 'preferred', 'normal', 'deprecated', 'preferred', 'normal' }) do
		table.insert(statements, buildStatementFromEntityId(1, rank))
	end
	for _, rank in ipairs({ 'preferred', 'preferred', 'normal', 'normal', 'deprecated', 'deprecated' }) do
		table.insert(expected, buildStatementFromEntityId(1, rank))
	end
	myModule.sortStatements(statements, { sort = 'rank' })
	self:assertDeepEquals(expected, statements)
end

function suite:testSortBySnaktype()
	local statements, expected = {}, {}
	for _, snak in ipairs({ 'somevalue', 'novalue', 'somevalue' }) do
		table.insert(statements, buildStatementFromSnaktype(snak))
	end
	table.insert(statements, 3, buildStatementFromEntityId(1))
	for _, snak in ipairs({ 'somevalue', 'somevalue', 'novalue' }) do
		table.insert(expected, buildStatementFromSnaktype(snak))
	end
	table.insert(expected, 1, buildStatementFromEntityId(1))
	myModule.sortStatements(statements, { sort = 'snaktype' })
	self:assertDeepEquals(expected, statements)
end

function suite:testSortHasLabel()
	local statements, expected = {}, {}
	for _, id in ipairs({ 6, 1, 1, 6, 6, 1 }) do
		table.insert(statements, buildStatementFromEntityId(id))
	end
	for _, id in ipairs({ 1, 1, 1, 6, 6, 6 }) do
		table.insert(expected, buildStatementFromEntityId(id))
	end
	myModule.sortStatements(statements, { sort = 'hasLabel' })
	self:assertDeepEquals(expected, statements)
end
]]--
return suite