Skip to content
24 changes: 19 additions & 5 deletions lua/spec/league_icon_spec.lua
Original file line number Diff line number Diff line change
Expand Up @@ -2,17 +2,27 @@
local LeagueIcon = require('Module:LeagueIcon')

local FILLER_EXPECT = '<span class="league-icon-small-image">[[File:Logo filler event.png|link=]]</span>'
local ICON_DARK_EXPECT = '<span class="league-icon-small-image">[[File:DarkIcon.png|link=||50x50px]]</span>'
local ICON_DARK_EXPECT = '<span class="league-icon-small-image">[[File:DarkIcon.png|link=|50x50px]]</span>'

local ICON_BOTH_EXPECT =
'<span class="league-icon-small-image lightmode">[[File:LightIcon.png|link=||50x50px]]</span>' ..
'<span class="league-icon-small-image darkmode">[[File:DarkIcon.png|link=||50x50px]]</span>'
'<span class="league-icon-small-image lightmode">[[File:LightIcon.png|link=|50x50px]]</span>' ..
'<span class="league-icon-small-image darkmode">[[File:DarkIcon.png|link=|50x50px]]</span>'
local ICON_WITH_LINK_EXPECT = '<span class="league-icon-small-image">[[File:Icon.png|link=link|name|50x50px]]</span>'
local ICON_WITH_LINK_BOTH_EXPECT =
'<span class="league-icon-small-image lightmode">[[File:LightIcon.png|link=link|name|50x50px]]</span>' ..
'<span class="league-icon-small-image darkmode">[[File:DarkIcon.png|link=link|name|50x50px]]</span>'

insulate('LeagueIcon.display', function()
local AddCategorySpy

before_each(function()
AddCategorySpy = spy.on(mw.ext.TeamLiquidIntegration, 'add_category')
end)

after_each(function()
AddCategorySpy:revert()
end)

it('should return filler icon when no icons are provided', function()
local args = {}
local result = LeagueIcon.display(args)
Expand All @@ -22,25 +32,29 @@ insulate('LeagueIcon.display', function()
it('should return iconDark when only iconDark is provided', function()
local args = {iconDark = 'DarkIcon.png'}
local result = LeagueIcon.display(args)
assert.are.equal(ICON_DARK_EXPECT .. '[[Category:Pages with only icondark]]', result)
assert.are.equal(ICON_DARK_EXPECT, result)
assert.stub(AddCategorySpy).was.called_with('Pages with only icondark')
end)

it('should return both icons when both icon and iconDark are provided', function()
local args = {icon = 'LightIcon.png', iconDark = 'DarkIcon.png'}
local result = LeagueIcon.display(args)
assert.are.equal(ICON_BOTH_EXPECT, result)
assert.stub(AddCategorySpy).was.called_at_most(0)
end)

it('should not use template when noTemplate option is true', function()
local args = {options = {noTemplate = true}}
local result = LeagueIcon.display(args)
assert.are.equal(FILLER_EXPECT, result)
assert.stub(AddCategorySpy).was.called_at_most(0)
end)

it('should not include link when noLink option is true', function()
local args = {icon = 'LightIcon.png', iconDark = 'DarkIcon.png', options = {noLink = true}}
local result = LeagueIcon.display(args)
assert.are.equal(ICON_BOTH_EXPECT, result)
assert.stub(AddCategorySpy).was.called_at_most(0)
end)
end)

Expand Down Expand Up @@ -109,7 +123,7 @@ end)
insulate('LeagueIcon.generate', function()
it('should generate code with valid arguments', function()
local args = {icon = 'Icon.png', link = 'link', name = 'name', series = 'series'}
GoldenTest('LeagueIcon.generate_copy_paste_gen', LeagueIcon.generate(args))
GoldenTest('LeagueIcon.generate_copy_paste_gen', tostring(LeagueIcon.generate(args)))
end)

it('should throw error when no link or series is provided', function()
Expand Down
147 changes: 93 additions & 54 deletions lua/wikis/commons/LeagueIcon.lua
Original file line number Diff line number Diff line change
Expand Up @@ -8,13 +8,18 @@
local Lua = require('Module:Lua')

local LeagueIcon = {}
local Array = Lua.import('Module:Array')
local Class = Lua.import('Module:Class')
local Template = Lua.import('Module:Template')
local Logic = Lua.import('Module:Logic')
local String = Lua.import('Module:StringUtils')

local FILLER = '<span class="league-icon-small-image">[[File:Logo filler event.png|link=]]</span>'
local NO_ICON_BUT_ICONDARK_TRACKING_CATEGORY = '[[Category:Pages with only icondark]]'
local Html = Lua.import('Module:Widget/Html')
local Link = Lua.import('Module:Widget/Basic/Link')
local WidgetUtil = Lua.import('Module:Widget/Util')

local FILLER_IMAGE = 'Logo filler event.png'
local NO_ICON_BUT_ICONDARK_TRACKING_CATEGORY = 'Pages with only icondark'

---@class LeagueIconDisplayArgs
---@field icon string?
Expand Down Expand Up @@ -42,21 +47,21 @@ function LeagueIcon.display(args)
local icon = args.icon
local trackingCategory = ''
if not Logic.readBool(options.noTemplate) and String.isEmpty(icon) and String.isEmpty(iconDark) then
local stringOfExpandedTemplate = LeagueIcon.getTemplate({
local stringOfExpandedTemplate = LeagueIcon.getTemplate{
series = args.series,
abbreviation = args.abbreviation,
date = args.date
})
icon, iconDark, trackingCategory = LeagueIcon.getIconFromTemplate({
}
icon, iconDark, trackingCategory = LeagueIcon.getIconFromTemplate{
icon = icon,
iconDark = iconDark,
stringOfExpandedTemplate = stringOfExpandedTemplate
})
}
end

--if icon and iconDark are not given and can not be retrieved return filler icon
if String.isEmpty(icon) and String.isEmpty(iconDark) then
return FILLER
return tostring(LeagueIcon._generateWikiCode(FILLER_IMAGE, ''))
end

if String.isEmpty(icon) then
Expand All @@ -76,9 +81,13 @@ function LeagueIcon.display(args)
else
link = args.link or args.series or args.abbreviation or args.name or ''
end
return LeagueIcon._make(icon, iconDark, link, args.name, size) .. trackingCategory
if String.isNotEmpty(trackingCategory) then
mw.ext.TeamLiquidIntegration.add_category(trackingCategory)
end
return LeagueIcon._make(icon, iconDark, link, args.name, size)
end

---@private
---@param icon string
---@param iconDark string
---@param link string
Expand All @@ -91,23 +100,38 @@ function LeagueIcon._make(icon, iconDark, link, name, size)
icon = string.gsub(icon, '^File:', '')
iconDark = string.gsub(iconDark, '^File:', '')

local imageOptions = '|link=' .. link .. '|' .. (name or link) .. '|' .. size .. 'x' .. size .. 'px]]'

if icon == iconDark then
return tostring(mw.html.create('span')
:addClass('league-icon-small-image')
:wikitext('[[File:' .. icon .. imageOptions))
return tostring(LeagueIcon._generateWikiCode(icon, link, name, size))
end

local lightSpan = mw.html.create('span')
:addClass('league-icon-small-image lightmode')
:wikitext('[[File:' .. icon .. imageOptions)
local darkSpan = mw.html.create('span')
:addClass('league-icon-small-image darkmode')
:wikitext('[[File:' .. iconDark .. imageOptions)
local lightSpan = LeagueIcon._generateWikiCode(icon, link, name, size, 'lightmode')
local darkSpan = LeagueIcon._generateWikiCode(iconDark, link, name, size, 'darkmode')
return tostring(lightSpan) .. tostring(darkSpan)
end

---@private
---@param icon string
---@param link string
---@param name string?
---@param size number?
---@param additionalClasses string|string[]?
---@return HtmlNode
function LeagueIcon._generateWikiCode(icon, link, name, size, additionalClasses)
return Html.Span{
classes = Array.extend('league-icon-small-image', additionalClasses),
children = {
'[[',
table.concat(Array.extend(
'File:' .. icon,
'link=' .. link,
Logic.emptyOr(name, link),
size and (size .. 'x' .. size .. 'px') or nil
), '|'),
']]'
Comment on lines +123 to +130
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why not use icon/image widget?

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

because everything has to be slapped with tostring() anyway to avoid existing usages breaking, I didn't bother to import it
either way I don't have a strong opinion

}
}
end

---Retrieve icon and iconDark from LeagueIconSmall templates
---@param args {icon: string?, iconDark: string?, stringOfExpandedTemplate: string?}
---@return string, string, string
Expand Down Expand Up @@ -190,48 +214,52 @@ end
--generate copy paste code for new LeagueIconSmall templates
--to be used with a form
---@param args LeagueIconGenerateArgs
---@return string
---@return Renderable
function LeagueIcon.generate(args)
local link = args.link or args.series
if String.isEmpty(link) then
error('No series/link specified')
end
assert(String.isNotEmpty(link), 'No series/link specified')
---@cast link -nil
local name = args.name or link

local icon = args.icon
if String.isEmpty(icon) then
error('No icon file specified')
end
local iconDark = args.iconDark or icon

local imageOptions = '|link={{{1|{{{link|' .. link .. '}}}}}}|{{{name|{{{1|{{{link|' .. name .. '}}}}}}}}}|50x50px]]'
assert(String.isNotEmpty(icon), 'No icon file specified')

return Html.Fragment{children = WidgetUtil.collect(
Html.Pre{
classes = {'selectall'},
children = {mw.text.nowiki(LeagueIcon._generateTemplateCode(icon, args.iconDark, link, name))}
},
LeagueIcon._buildLinkToTemplate(args)
)}
end

if icon == iconDark then
return '<pre class="selectall" width=50%>' .. mw.text.nowiki(
'<span class="league-icon-small-image">' ..
'[[File:' .. icon .. imageOptions .. '</span><!--\n' ..
'--><noinclude>[[Category:Small League Icon Templates]]</noinclude>') .. '</pre>'
.. LeagueIcon._buildLinkToTemplate(args)
---@private
---@param icon string
---@param iconDark string?
---@param link string
---@param name string
---@return string
function LeagueIcon._generateTemplateCode(icon, iconDark, link, name)
local linkOption = '{{{1|{{{link|' .. link .. '}}}}}}'
local nameOption = '{{{name|{{{1|{{{link|' .. name .. '}}}}}}}}}'
if String.isEmpty(iconDark) or icon == iconDark then
return tostring(LeagueIcon._generateWikiCode(icon, linkOption, nameOption, 50))
.. '<!--\n--><noinclude>[[Category:Small League Icon Templates]]</noinclude>'
end

return '<pre class="selectall" width=50%>' .. mw.text.nowiki(
'<span class="league-icon-small-image lightmode">' ..
'[[File:' .. icon .. imageOptions .. '</span><!--\n' ..
'--><span class="league-icon-small-image darkmode">' ..
'[[File:' .. iconDark .. imageOptions .. '</span><!--\n' ..
'--><noinclude>[[Category:Small League Icon Templates]]</noinclude>') .. '</pre>'
.. LeagueIcon._buildLinkToTemplate(args)
---@cast iconDark -nil
return tostring(LeagueIcon._generateWikiCode(icon, linkOption, nameOption, 50, 'lightmode'))
.. '<!--\n-->'
.. tostring(LeagueIcon._generateWikiCode(iconDark, linkOption, nameOption, 50, 'darkmode'))
.. '<!--\n--><noinclude>[[Category:Small League Icon Templates]]</noinclude>'
end

--generate copy paste code for new historical LeagueIconSmall templates
--to be used with a form
---@param args table
---@return string
---@return HtmlNode
function LeagueIcon.generateHistorical(args)
local title = args.title or args.series
if String.isEmpty(title) then
error('No template title specified')
end
assert(String.isNotEmpty(title), 'No template title specified')
local link = args.link or title
local name = args.name or link
local timeName = title:lower() .. 'time'
Expand Down Expand Up @@ -272,20 +300,31 @@ function LeagueIcon.generateHistorical(args)
end
comparisons = '-->{{#ifexpr:' .. comparisons

return '<pre class="selectall" width=50%>' .. mw.text.nowiki(
defineTime .. comparisons .. '--><noinclude>[[Category:Historical Small League Icon template]]</noinclude>'
) .. '</pre>' .. LeagueIcon._buildLinkToTemplate(args)
return Html.Fragment{children = WidgetUtil.collect(
Html.Pre{
classes = {'selectall'},
children = {mw.text.nowiki(
defineTime .. comparisons .. '--><noinclude>[[Category:Historical Small League Icon template]]</noinclude>'
)}
},
LeagueIcon._buildLinkToTemplate(args)
)}
end

---@private
---@param args {templateName: string?, wiki: string?}
---@return string
---@return Renderable[]?
function LeagueIcon._buildLinkToTemplate(args)
if String.isEmpty(args.templateName) or String.isEmpty(args.wiki) then
return ''
return
end

return '<br><b>Link to the template page:</b> [[' .. args.wiki ..
':Template:LeagueIconSmall/' .. args.templateName:lower() .. ']]'
return {
Html.Br{},
Html.B{children = {'Link to the template page:'}},
' ',
Link{link = args.wiki .. ':Template:LeagueIconSmall/' .. args.templateName:lower()}
}
end

return Class.export(LeagueIcon, {frameOnly = true, exports = {
Expand Down
Loading