[locale] Approach matching from a different angle
- add struct that splits a locale name into parts - add tests that the splitting and joining works
This commit is contained in:
parent
84c0da2186
commit
fd56b5bdc4
@ -22,6 +22,7 @@ calamares_add_plugin(locale
|
||||
Config.cpp
|
||||
LCLocaleDialog.cpp
|
||||
LocaleConfiguration.cpp
|
||||
LocaleNames.cpp
|
||||
LocalePage.cpp
|
||||
LocaleViewStep.cpp
|
||||
SetTimezoneJob.cpp
|
||||
@ -39,7 +40,7 @@ calamares_add_plugin(locale
|
||||
|
||||
calamares_add_test(
|
||||
localetest
|
||||
SOURCES Tests.cpp Config.cpp LocaleConfiguration.cpp SetTimezoneJob.cpp timezonewidget/TimeZoneImage.cpp
|
||||
SOURCES Tests.cpp Config.cpp LocaleConfiguration.cpp LocaleNames.cpp SetTimezoneJob.cpp timezonewidget/TimeZoneImage.cpp
|
||||
DEFINITIONS SOURCE_DIR="${CMAKE_CURRENT_LIST_DIR}/images" DEBUG_TIMEZONES=1
|
||||
LIBRARIES Qt5::Gui
|
||||
)
|
||||
|
72
src/modules/locale/LocaleNames.cpp
Normal file
72
src/modules/locale/LocaleNames.cpp
Normal file
@ -0,0 +1,72 @@
|
||||
/* === This file is part of Calamares - <https://calamares.io> ===
|
||||
*
|
||||
* SPDX-FileCopyrightText: 2022 Adriaan de Groot <groot@kde.org>
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*
|
||||
* Calamares is Free Software: see the License-Identifier above.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "LocaleNames.h"
|
||||
|
||||
#include "utils/Logger.h"
|
||||
|
||||
#include <QRegularExpression>
|
||||
|
||||
LocaleNameParts
|
||||
LocaleNameParts::fromName( const QString& name )
|
||||
{
|
||||
auto requireAndRemoveLeadingChar = []( QChar c, QString s )
|
||||
{
|
||||
if ( s.startsWith( c ) )
|
||||
{
|
||||
return s.remove( 0, 1 );
|
||||
}
|
||||
else
|
||||
{
|
||||
return QString();
|
||||
}
|
||||
};
|
||||
|
||||
auto parts = QRegularExpression( "^([a-zA-Z]+)(_[a-zA-Z]+)?(\\.[-a-zA-Z0-9]+)?(@[a-zA-Z]+)?" ).match( name );
|
||||
const QString calamaresLanguage = parts.captured( 1 );
|
||||
const QString calamaresCountry = requireAndRemoveLeadingChar( '_', parts.captured( 2 ) );
|
||||
const QString calamaresEncoding = requireAndRemoveLeadingChar( '.', parts.captured( 3 ) );
|
||||
const QString calamaresRegion = requireAndRemoveLeadingChar( '@', parts.captured( 4 ) );
|
||||
|
||||
if ( calamaresLanguage.isEmpty() )
|
||||
{
|
||||
return LocaleNameParts {};
|
||||
}
|
||||
else
|
||||
{
|
||||
return LocaleNameParts { calamaresLanguage, calamaresCountry, calamaresRegion, calamaresEncoding };
|
||||
}
|
||||
}
|
||||
|
||||
QString
|
||||
LocaleNameParts::name() const
|
||||
{
|
||||
// We don't want QStringView to a temporary; force conversion
|
||||
auto insertLeadingChar = []( QChar c, QString s ) -> QString
|
||||
{
|
||||
if ( s.isEmpty() )
|
||||
{
|
||||
return QString();
|
||||
}
|
||||
else
|
||||
{
|
||||
return c + s;
|
||||
}
|
||||
};
|
||||
|
||||
if ( !isValid() )
|
||||
{
|
||||
return QString();
|
||||
}
|
||||
else
|
||||
{
|
||||
return language + insertLeadingChar( '_', country ) + insertLeadingChar( '.', encoding )
|
||||
+ insertLeadingChar( '@', region );
|
||||
}
|
||||
}
|
35
src/modules/locale/LocaleNames.h
Normal file
35
src/modules/locale/LocaleNames.h
Normal file
@ -0,0 +1,35 @@
|
||||
/* === This file is part of Calamares - <https://calamares.io> ===
|
||||
*
|
||||
* SPDX-FileCopyrightText: 2022 Adriaan de Groot <groot@kde.org>
|
||||
* SPDX-License-Identifier: GPL-3.0-or-later
|
||||
*
|
||||
* Calamares is Free Software: see the License-Identifier above.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LOCALENAMES_H
|
||||
#define LOCALENAMES_H
|
||||
|
||||
#include <QString>
|
||||
|
||||
/** @brief parts of a locale-name (e.g. "ar_LY.UTF-8", split apart)
|
||||
*
|
||||
* These are created from lines in `/usr/share/i18n/SUPPORTED`,
|
||||
* which lists all the locales supported by the system (there
|
||||
* are also other sources of the same).
|
||||
*
|
||||
*/
|
||||
struct LocaleNameParts
|
||||
{
|
||||
QString language; // e.g. "ar"
|
||||
QString country; // e.g. "LY" (may be empty)
|
||||
QString region; // e.g. "@valencia" (may be empty)
|
||||
QString encoding; // e.g. "UTF-8" (may be empty)
|
||||
|
||||
bool isValid() const { return !language.isEmpty(); }
|
||||
QString name() const;
|
||||
|
||||
static LocaleNameParts fromName( const QString& name );
|
||||
};
|
||||
|
||||
#endif
|
@ -9,6 +9,7 @@
|
||||
|
||||
#include "Config.h"
|
||||
#include "LocaleConfiguration.h"
|
||||
#include "LocaleNames.h"
|
||||
#include "timezonewidget/TimeZoneImage.h"
|
||||
|
||||
#include "Settings.h"
|
||||
@ -49,8 +50,11 @@ private Q_SLOTS:
|
||||
void testLanguageDetection();
|
||||
void testLanguageDetectionValencia();
|
||||
|
||||
// Check realistic language mapping for issue 2008
|
||||
// Check that the test-data is available and ok
|
||||
void testKDENeonLanguageData();
|
||||
void testLocaleNameParts();
|
||||
|
||||
// Check realistic language mapping for issue 2008
|
||||
void testLanguageMappingNeon_data();
|
||||
void testLanguageMappingNeon();
|
||||
void testLanguageMappingFreeBSD_data();
|
||||
@ -392,6 +396,10 @@ splitTestFileIntoLines( const QString& filename )
|
||||
void
|
||||
LocaleTests::testKDENeonLanguageData()
|
||||
{
|
||||
if ( !m_KDEneonLocales.isEmpty() )
|
||||
{
|
||||
return;
|
||||
}
|
||||
const QStringList neonLocales = splitTestFileIntoLines( QStringLiteral( "locale-data-neon" ) );
|
||||
cDebug() << "Loaded KDE neon locales test data" << neonLocales.front() << "to" << neonLocales.back();
|
||||
QCOMPARE( neonLocales.length(), 318 ); // wc -l tells me 318 lines
|
||||
@ -442,12 +450,14 @@ LocaleTests::MappingData()
|
||||
}
|
||||
|
||||
|
||||
void LocaleTests::testLanguageMappingNeon_data()
|
||||
void
|
||||
LocaleTests::testLanguageMappingNeon_data()
|
||||
{
|
||||
MappingData();
|
||||
}
|
||||
|
||||
void LocaleTests::testLanguageMappingFreeBSD_data()
|
||||
void
|
||||
LocaleTests::testLanguageMappingFreeBSD_data()
|
||||
{
|
||||
MappingData();
|
||||
}
|
||||
@ -455,6 +465,7 @@ void LocaleTests::testLanguageMappingFreeBSD_data()
|
||||
void
|
||||
LocaleTests::testLanguageMappingNeon()
|
||||
{
|
||||
testKDENeonLanguageData();
|
||||
QVERIFY( !m_KDEneonLocales.isEmpty() );
|
||||
|
||||
QFETCH( QString, selectedLanguage );
|
||||
@ -471,6 +482,7 @@ LocaleTests::testLanguageMappingNeon()
|
||||
void
|
||||
LocaleTests::testLanguageMappingFreeBSD()
|
||||
{
|
||||
testKDENeonLanguageData();
|
||||
QVERIFY( !m_FreeBSDLocales.isEmpty() );
|
||||
|
||||
QFETCH( QString, selectedLanguage );
|
||||
@ -485,6 +497,45 @@ LocaleTests::testLanguageMappingFreeBSD()
|
||||
QCOMPARE( bsd.language(), expected );
|
||||
}
|
||||
|
||||
void
|
||||
LocaleTests::testLocaleNameParts()
|
||||
{
|
||||
testKDENeonLanguageData();
|
||||
QVERIFY( !m_FreeBSDLocales.isEmpty() );
|
||||
QVERIFY( !m_KDEneonLocales.isEmpty() );
|
||||
|
||||
// Example constant locales
|
||||
{
|
||||
auto c_parts = LocaleNameParts::fromName( QStringLiteral( "nl_NL.UTF-8" ) );
|
||||
QCOMPARE( c_parts.language, QStringLiteral( "nl" ) );
|
||||
QCOMPARE( c_parts.country, QStringLiteral( "NL" ) );
|
||||
QCOMPARE( c_parts.encoding, QStringLiteral( "UTF-8" ) );
|
||||
QVERIFY( c_parts.region.isEmpty() );
|
||||
}
|
||||
{
|
||||
auto c_parts = LocaleNameParts::fromName( QStringLiteral( "C.UTF-8" ) );
|
||||
QCOMPARE( c_parts.language, QStringLiteral( "C" ) );
|
||||
QVERIFY( c_parts.country.isEmpty() );
|
||||
QCOMPARE( c_parts.encoding, QStringLiteral( "UTF-8" ) );
|
||||
QVERIFY( c_parts.region.isEmpty() );
|
||||
}
|
||||
|
||||
// Check all the loaded test locales
|
||||
for ( const auto& s : m_FreeBSDLocales )
|
||||
{
|
||||
auto parts = LocaleNameParts::fromName( s );
|
||||
QVERIFY( parts.isValid() );
|
||||
QCOMPARE( parts.name(), s );
|
||||
}
|
||||
|
||||
for ( const auto& s : m_KDEneonLocales )
|
||||
{
|
||||
auto parts = LocaleNameParts::fromName( s );
|
||||
QVERIFY( parts.isValid() );
|
||||
QCOMPARE( parts.name(), s );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#include "utils/moc-warnings.h"
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user