local tests = require "Module:UnitTests"
local rhyme = require "Module:fi-pronunciation".generate_rhyme
local syllabify = require "Module:fi-pronunciation".syllabify
local to_IPA = require "Module:fi-pronunciation".fi_IPA_term
local add_rhythmic_stress = require "Module:fi-pronunciation".add_rhythmic_stress
local function link_fi(term)
return '<span class="Latn" lang="fi">[[' .. term .. "#Finnish|" .. term .. ']]</span>'
end
local function tag_IPA(transcription)
return '<span class="IPA">' .. transcription .. '</span>'
end
function tests:test_IPA_phonemic()
local IPA_testcases = {
"nonsyllabic",
{ "vain", "ˈʋɑi̯n" },
{ "punainen", "ˈpunɑi̯nen" },
{ "kausi", "ˈkɑu̯si" },
{ "hajautua", "ˈhɑjɑu̯tuɑ" },
{ "hajauttaa", "ˈhɑjɑutːɑː" },
{ "kieli", "ˈkie̯li" },
{ "kuori", "ˈkuo̯ri" },
{ "pyörä", "ˈpyø̯ræ" },
{ "vakuoli", "ˈʋɑkuoli" },
{ "seota", "ˈseotɑ" },
}
local options = { display = tag_IPA }
self:iterate(IPA_testcases,
function (self, term, expected, respelling)
self:equals(
link_fi(term)
.. (respelling and " (<kbd>" .. respelling .. "</kbd>)" or ""),
to_IPA(respelling or term),
expected, options)
end)
end
function tests:test_IPA_phonetic()
local IPA_testcases = {
"h",
{ "vihma", "ˈʋiçmɑ̝" },
{ "yhtiö", "ˈyçt̪iø̞" },
{ "maha", "ˈmɑ̝ɦɑ̝" },
{ "mahti", "ˈmɑ̝xt̪i" },
{ "kohme", "ˈko̞xme̞" },
{ "tuhka", "ˈt̪uxkɑ̝" },
"velar nasal",
{ "ongelma", "ˈo̞ŋːe̞lmɑ̝" },
"vowel sequences",
{ "vuosi", "ˈʋuo̞̯s̠i" },
{ "ien", "ˈie̞̯n" },
{ "spanieli", "ˈs̠pɑ̝niˌe̞li" },
{ "hajauttaa", "ˈhɑ̝jɑ̝ˌut̪ːɑ̝ː" },
{ "hajautua", "ˈhɑ̝jɑ̝u̯ˌt̪uɑ̝" },
"secondary stress",
{ "yläosa", "ˈylæˌo̞s̠ɑ̝", "ylä-osa" },
"* in narrow transcription",
{ "tietokoneajo", "ˈt̪ie̞̯t̪o̞ˌko̞ne̞ˌ(ʔ)ɑ̝jo̞", "tieto-kone*-ajo" },
{ "tervetuloa", "ˈt̪e̞rʋe̞t̪̚ˌt̪ulo̞ɑ̝", "terve*-tuloa" },
{ "pistenäyttö", "ˈpis̠te̞nˌnæy̯t̪ːø̞", "piste*-näyttö" },
{ "terve", "ˈt̪e̞rʋe̞(ʔ)", "terve*" },
"secondary stress in narrow transcription",
{ "asetyyli", "ˈɑ̝s̠e̞ˌt̪yːli" },
{ "mokoma", "ˈmo̞ko̞mɑ̝" },
{ "yhdyssana", "ˈyçdys̠ˌs̠ɑ̝nɑ̝", "yhdys-sana" },
{ "papiljotti", "ˈpɑ̝pilˌjo̞t̪ːi" },
{ "matematiikassani", "ˈmɑ̝t̪e̞mɑ̝ˌt̪iːkɑ̝s̠ˌs̠ɑ̝ni" },
{ "perustelemattomalta", "ˈpe̞rus̠te̞le̞ˌmɑ̝t̪ːo̞ˌmɑ̝l̪t̪ɑ̝" },
"misc",
{ "katse", "ˈkɑ̝ts̠e̞(ʔ)", "katse*" },
{ "kunpa", "ˈkumpɑ̝" },
}
local options = { display = tag_IPA }
self:iterate(IPA_testcases,
function (self, term, expected, respelling)
self:equals(
link_fi(term)
.. (respelling and " (<kbd>" .. respelling .. "</kbd>)" or ""),
to_IPA(respelling or term, true),
expected, options)
end)
end
function tests:test_rhyme_detection()
local examples = {
"rhyme detection",
{ "kala", "ɑlɑ" },
{ "lehto", "ehto" },
{ "ehto", "ehto" },
{ "yö", "yø" },
{ "omenanamme", "ɑmːe" },
{ "liu'utus", "iu.utus" }, -- iuʔutus
}
local options = { display = tag_IPA }
self:iterate(examples,
function (self, term, expected, respelling)
self:equals(
link_fi(term)
.. (respelling and " (<kbd>" .. respelling .. "</kbd>)" or ""),
rhyme(respelling or term, true),
expected, options)
end)
end
function tests:test_rhythmic_stress()
local rhythmic_stress_testcases = {
"LTR/RTL rhythmic stress assignment",
{ "asetyyli", "aseˌtyyli", "aseˌtyyli" },
{ "mokoma", "mokoma", "mokoma" },
{ "yhdyssana", "yhdys-sana", "yhdys-sana", "yhdys-sana" },
{ "papiljotti", "papilˌjotti", "papilˌjotti" },
{ "matematiikassani", "matemaˌtiikasˌsani", "mateˌmatiiˌkassani" },
{ "perustelemattomalta", "perusteleˌmattoˌmalta", "perusˌteleˌmattoˌmalta" },
{ "sukulaisellani", "sukuˌlaiselˌlani", "sukulaiˌsellani" },
{ "ailurofobian", "ailuˌrofoˌbian", "ailuroˌfobian" },
-- RTL examples from Karvonen (2005)
{ "monopoli", "monoˌpoli", "monoˌpoli" },
{ "kolesteroli", "kolesˌteroli", "kolesteˌroli" },
{ "televisio", "teleˌvisio", "teleˌvisio" },
{ "postpositio", "post.poˌsitio", "post.poˌsitio", "post.positio" },
{ "dodekaedri", "dodekaˌedri", "dodekaˌedri" },
{ "sinfonia", "sinfoˌnia", "sinfonia" },
{ "laboratorio", "laboˌratoˌrio", "laboraˌtorio" },
{ "bibliografia", "bibliˌo.graˌfia", "biblioˌgrafia", "biblio.grafia" },
{ "kinematografi", "kineˌmatoˌgrafi", "kineˌmatoˌgrafi", "kinemato.grafi" },
{ "helikopteri", "heliˌkopteri", "heliˌkopteri" },
{ "katamaraani", "katamaˌraani", "katamaˌraani" },
{ "syntetisaattori", "syntetiˌsaattori", "syntetiˌsaattori" },
{ "horisontaali", "horiˌsontaali", "horisonˌtaali" },
{ "akateemikko", "akaˌteemikko", "akaˌteemikko" },
{ "elementaarinen", "eleˌmentaaˌrinen", "elemenˌtaarinen" },
{ "konsonantismi", "konsoˌnantismi", "konsonanˌtismi" },
{ "televisiot", "teleˌvisiot", "teleˌvisiot" },
{ "ravintolat", "ravinˌtolat", "ravinˌtolat" },
{ "professorilla", "professoˌrilla", "professoˌrilla" },
{ "salasanassa", "sala-sanassa", "sala-sanassa", "sala-sanassa" },
{ "esplanadilla", "es.pla+nadilla", "es.pla+nadilla", "es.pla+nadilla" },
}
options = { }
self:iterate(rhythmic_stress_testcases,
function (self, term, expected_ltr, expected_rtl, respelling)
local spelling = respelling or term
local actual_ltr = add_rhythmic_stress(spelling, false)
local actual_rtl = add_rhythmic_stress(spelling, true)
self:equals(
link_fi(term)
.. (respelling and " (<kbd>" .. respelling .. "</kbd>)" or ""),
actual_ltr .. "//" .. actual_rtl,
mw.ustring.gsub(expected_ltr .. "//" .. expected_rtl, "ˌ", "ˌ"), options)
end)
local rhythmic_stress_last_heavy_testcases = {
"LTR/RTL rhythmic stress assignment (last syllable heavy, penultimate light)",
-- see Karvonen (2005)
{ "omenat", "omeˌnat", "omeˌnat" },
{ "televisiot", "teleˌvisiˌot", "teleˌvisiˌot" },
{ "matalaa", "mataˌlaa", "mataˌlaa" },
{ "ravintolat", "ravintoˌlat", "ravintoˌlat" },
{ "ailurofobian", "ailuˌrofobiˌan", "ailuroˌfobiˌan" },
}
options = { }
self:iterate(rhythmic_stress_last_heavy_testcases,
function (self, term, expected_ltr, expected_rtl, respelling)
local spelling = respelling or term
local actual_ltr = select(2, add_rhythmic_stress(spelling, false))
local actual_rtl = select(2, add_rhythmic_stress(spelling, true))
self:equals(
link_fi(term)
.. (respelling and " (<kbd>" .. respelling .. "</kbd>)" or ""),
actual_ltr .. "//" .. actual_rtl,
mw.ustring.gsub(expected_ltr .. "//" .. expected_rtl, "ˌ", "ˌ"), options)
end)
end
function tests:test_syllabify()
local examples = {
{ "kuitenkin", "kui-ten-kin" },
{ "seassa", "se-as-sa" },
{ "piano", "pi-a-no" },
{ "geometria", "ge-o-met-ri-a" },
{ "aurinko", "au-rin-ko" },
{ "kissa", "kis-sa" },
{ "määrä", "mää-rä" },
{ "kuorma-auto", "kuor-ma-au-to" },
{ "vaa’an", "vaa-an" },
{ "kolmivaihekilowattituntimittari", "kol-mi-vai-he-ki-lo-wat-ti-tun-ti-mit-ta-ri", "kolmi-vaihe-kilo-watti-tunti-mittari" },
{ "hajautua", "ha-jau-tu-a" },
{ "hajauttaa", "ha-ja-ut-taa" },
{ "saippuakivikauppias", "saip-pu-a-ki-vi-kaup-pi-as", "saippua-kivi-kauppias" },
{ "lämmityskulut", "läm-mi-tys-ku-lut", "lämmitys-kulut" },
{ "sosiaalitieteet", "so-si-aa-li-tie-teet", "sosiaali-tieteet" },
}
local options = {}
self:iterate(examples,
function (self, term, expected, respelling)
self:equals(
link_fi(term),
table.concat(syllabify(respelling or term), "-"),
expected, options)
end)
end
return tests