[locale] Introduce a similarity-score for locales

This commit is contained in:
Adriaan de Groot 2022-08-14 16:26:46 +02:00
parent fd56b5bdc4
commit 78e216fedb
3 changed files with 66 additions and 0 deletions

View File

@ -70,3 +70,21 @@ LocaleNameParts::name() const
+ insertLeadingChar( '@', region );
}
}
int
LocaleNameParts::similarity( const LocaleNameParts& other ) const
{
if ( !isValid() || !other.isValid() )
{
return 0;
}
if ( language != other.language )
{
return 0;
}
const auto matched_region = ( region == other.region ? 30 : 0 );
const auto matched_country = ( country == other.country ? 20 : 0 );
const auto no_other_country_given = ( ( country != other.country && other.country.isEmpty() ) ? 10 : 0 );
return 50 + matched_region + matched_country + no_other_country_given;
}

View File

@ -30,6 +30,14 @@ struct LocaleNameParts
QString name() const;
static LocaleNameParts fromName( const QString& name );
/** @brief Compute similarity-score with another locale-name.
*
* Similarity is driven by language and region, then country.
* Returns a number between 0 (no similarity, e.g. the
* language is different) and 100 (complete match).
*/
int similarity( const LocaleNameParts& other ) const;
};
#endif

View File

@ -59,6 +59,7 @@ private Q_SLOTS:
void testLanguageMappingNeon();
void testLanguageMappingFreeBSD_data();
void testLanguageMappingFreeBSD();
void testLanguageSimilarity();
private:
QStringList m_KDEneonLocales;
@ -536,6 +537,45 @@ LocaleTests::testLocaleNameParts()
}
}
void
LocaleTests::testLanguageSimilarity()
{
// Empty
{
QCOMPARE( LocaleNameParts().similarity( LocaleNameParts() ), 0 );
}
// Some simple Dutch situations
{
auto nl_parts = LocaleNameParts::fromName( QStringLiteral( "nl_NL.UTF-8" ) );
auto be_parts = LocaleNameParts::fromName( QStringLiteral( "nl_BE.UTF-8" ) );
auto nl_short_parts = LocaleNameParts::fromName( QStringLiteral( "nl" ) );
QCOMPARE( nl_parts.similarity( nl_parts ), 100 );
QCOMPARE( nl_parts.similarity( LocaleNameParts() ), 0 );
QCOMPARE( nl_parts.similarity( be_parts ), 80 ); // Language + (empty) region match
QCOMPARE( nl_parts.similarity( nl_short_parts ), 90 );
}
// Everything matches itself
{
if ( m_KDEneonLocales.isEmpty() )
{
testKDENeonLanguageData();
}
QVERIFY( !m_FreeBSDLocales.isEmpty() );
QVERIFY( !m_KDEneonLocales.isEmpty() );
for ( const auto& l : m_KDEneonLocales )
{
auto locale_name = LocaleNameParts::fromName( l );
auto self_similarity = locale_name.similarity( locale_name );
if ( self_similarity != 100 )
{
cDebug() << "Locale" << l << "is unusual.";
}
QCOMPARE( self_similarity, 100 );
}
}
}
#include "utils/moc-warnings.h"