<commit_before>/***************************************************************************
**
** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (<EMAIL>)
**
** This file is part of libmeegotouch.
**
** If you have questions regarding the use of this file, please contact
** Nokia at <EMAIL>.
**
** This library is free software; you can redistribute it and/or
** modify it under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation
** and appearing in the file LICENSE.LGPL included in the packaging
** of this file.
**
****************************************************************************/

#include <QCoreApplication>
#include <QTextCodec>
#include <MLocale>
#include <unicode/uversion.h>

#include "ut_mcalendar.h"

void Ut_MCalendar::initTestCase()
{
    static int argc = 0;
    static char *argv[1] = { (char *) "" };
    qap = new QCoreApplication(argc, argv);
    QTextCodec::setCodecForCStrings(QTextCodec::codecForName("UTF-8"));
    QProcess process;
    process.start("sh -c \"dpkg -s libicu44 | grep Version | perl -pe 's/^Version:[[:space:]]*([^[[:space:]]+)$/$1/g'\"");
    if (!process.waitForFinished()) {
        qDebug() << "cannot run process to check libicu44 package version , exiting ...";
        exit(1);
    }
    icuPackageVersion = process.readAllStandardOutput();
    icuPackageVersion.replace("\n", "");
    qDebug() << "libicu44 package version is:" << icuPackageVersion;
}

void Ut_MCalendar::cleanupTestCase()
{
    delete qap;
}

void Ut_MCalendar::init()
{
    // most tests use the Finnish timezone:
    MCalendar::setSystemTimeZone("Europe/Helsinki");
}

void Ut_MCalendar::cleanup()
{
}

void Ut_MCalendar::testTimeZones()
{
    qDebug() << "systemTimeZone() =" << MCalendar::systemTimeZone();
    MCalendar::setSystemTimeZone("Europe/Helsinki");
    QCOMPARE(MCalendar::systemTimeZone(), QString("Europe/Helsinki"));
    foreach (QString timeZone, MCalendar::supportedTimeZones()) {
        MCalendar::setSystemTimeZone(timeZone);
        QCOMPARE(MCalendar::systemTimeZone(), timeZone);
    }
}

void Ut_MCalendar::testTimeZonesInCountry_data()
{
    QTest::addColumn<QString>("countryCode");
    QTest::addColumn<QStringList>("timeZoneList");

    QTest::newRow("FI")
        << "FI"
        << (QStringList() << "Europe/Helsinki");
    QTest::newRow("JP")
        << "JP"
        << (QStringList() << "Asia/Tokyo" << "JST" << "Japan");
}

void Ut_MCalendar::testTimeZonesInCountry()
{
    QFETCH(QString, countryCode);
    QFETCH(QStringList, timeZoneList);
    QCOMPARE(MCalendar::supportedTimeZones(countryCode), timeZoneList);
}

void Ut_MCalendar::testConversionFromAndToQDateTime_data()
{
    QTest::addColumn<QDate>("qDate");
    QTest::addColumn<QTime>("qTime");
    QTest::addColumn<int>("qTimeSpec");
    QTest::addColumn<QString>("timeZone");

    QTest::newRow("1945-07-21 Qt::Localtime UTC")
            << QDate(1945, 7, 31)
            << QTime(14, 31, 0, 0)
            << (int) Qt::LocalTime
            << "UTC";

    QTest::newRow("1963-07-21 Qt::Localtime UTC")
            << QDate(1963, 7, 31)
            << QTime(14, 31, 0, 0)
            << (int) Qt::LocalTime
            << "UTC";

    QTest::newRow("2040-07-21 Qt::Localtime UTC")
            << QDate(2040, 7, 31)
            << QTime(14, 31, 0, 0)
            << (int) Qt::LocalTime
            << "UTC";

    QTest::newRow("2050-07-21 Qt::Localtime UTC")
            << QDate(2050, 7, 31)
            << QTime(14, 31, 0, 0)
            << (int) Qt::LocalTime
            << "UTC";

    QTest::newRow("2068-07-21 Qt::Localtime UTC")
            << QDate(2068, 7, 31)
            << QTime(14, 31, 0, 0)
            << (int) Qt::LocalTime
            << "UTC";

    QTest::newRow("2008-07-21 Qt::Localtime UTC")
            << QDate(2008, 7, 21)
            << QTime(12, 31, 0, 0)
            << (int) Qt::LocalTime
            << "UTC";

    QTest::newRow("2008-07-21 Qt::UTC UTC")
            << QDate(2008, 7, 21)
            << QTime(12, 31, 0, 0)
            << (int) Qt::UTC
            << "UTC";

    QTest::newRow("2008-07-21 Qt::LocalTime Europe/Helsinki")
            << QDate(2008, 7, 21)
            << QTime(12, 31, 0, 0)
            << (int) Qt::LocalTime
            << "Europe/Helsinki";

    QTest::newRow("2008-07-21 Qt::UTC Europe/Helsinki")
            << QDate(2008, 7, 21)
            << QTime(12, 31, 0, 0)
            << (int) Qt::UTC
            << "Europe/Helsinki";
}

void Ut_MCalendar::testConversionFromAndToQDateTime()
{
    QFETCH(QDate, qDate);
    QFETCH(QTime, qTime);
    QFETCH(int, qTimeSpec);
    QFETCH(QString, timeZone);

    MCalendar::setSystemTimeZone(timeZone);

    MCalendar mcal;
    QDateTime datetime(qDate, qTime, (Qt::TimeSpec) qTimeSpec);
    mcal.setDateTime(datetime);
    QCOMPARE(mcal.qDateTime((Qt::TimeSpec) qTimeSpec), datetime);
}

void Ut_MCalendar::testIcuFormatString_data()
{
    QTest::addColumn<QString>("language");
    QTest::addColumn<QString>("lcMessages");
    QTest::addColumn<QString>("lcTime");
    QTest::addColumn<MLocale::CalendarType>("calendarType");
    QTest::addColumn<QString>("dateShortResult");
    QTest::addColumn<QString>("dateMediumResult");
    QTest::addColumn<QString>("dateLongResult");
    QTest::addColumn<QString>("dateFullResult");
    QTest::addColumn<QString>("timeShortResult");
    QTest::addColumn<QString>("timeMediumResult");
    QTest::addColumn<QString>("timeLongResult");
    QTest::addColumn<QString>("timeFullResult");

    QTest::newRow("de_DE, Gregorian calendar")
        << "fi_FI" // language does not matter unless lc_time is empty
        << "fi_FI" // lc_messages does not matter
        << "de_DE" // only lc_time matters
        << MLocale::GregorianCalendar
        << "dd.MM.yy"
        << "dd.MM.yyyy"
        << "d. MMMM y"
        << "EEEE, d. MMMM y"
        << "HH:mm"
        << "HH:mm:ss"
        << "HH:mm:ss z"
        << "HH:mm:ss zzzz";

    QTest::newRow("fi_FI, Gregorian calendar")
        << "de_DE" // language does not matter unless lc_time is empty
        << "de_DE" // lc_messages does not matter
        << "fi_FI" // only lc_time matters
        << MLocale::GregorianCalendar
        << "d.M.yyyy"
        << "d.M.yyyy"
        << "d. MMMM y"
        << "cccc d. MMMM y"
        << "H.mm"
        << "H.mm.ss"
        << "H.mm.ss z"
        << "H.mm.ss zzzz";

    QTest::newRow("fi_FI, Gregorian calendar")
        << "fi_FI" // language does not matter unless lc_time is empty
        << "de_DE" // lc_messages does not matter
        << "" // only lc_time matters
        << MLocale::GregorianCalendar
        << "d.M.yyyy"
        << "d.M.yyyy"
        << "d. MMMM y"
        << "cccc d. MMMM y"
        << "H.mm"
        << "H.mm.ss"
        << "H.mm.ss z"
        << "H.mm.ss zzzz";

    QTest::newRow("fi_FI, Islamic calendar")
        << "fi_FI" // language does not matter unless lc_time is empty
        << "de_DE" // lc_messages does not matter
        << "" // only lc_time matters
        << MLocale::IslamicCalendar
        << "d.M.yyyy"
        << "d.M.yyyy"
        << "d. MMMM y"
        << "cccc d. MMMM y"
        << "H.mm"
        << "H.mm.ss"
        << "H.mm.ss z"
        << "H.mm.ss zzzz";

    QTest::newRow("Arabic, Gregorian calendar")
        << "fi_FI" // language does not matter unless lc_time is empty
        << "de_DE" // lc_messages does not matter
        << "ar_EG" // only lc_time matters
        << MLocale::GregorianCalendar
        << "d‏/M‏/yyyy"   // contains U+200F RIGHT-TO-LEFT MARK
        << "dd‏/MM‏/yyyy" // contains U+200F RIGHT-TO-LEFT MARK
        << "d MMMM، y"
        << "EEEE، d MMMM، y"
        << "h:mm a"
        << "h:mm:ss a"
        << "z h:mm:ss a"
        << "zzzz h:mm:ss a";

    QTest::newRow("Arabic, Islamic calendar")
        << "fi_FI" // language does not matter unless lc_time is empty
        << "de_DE" // lc_messages does not matter
        << "ar_EG" // only lc_time matters
        << MLocale::IslamicCalendar
        << "d‏/M‏/yyyy"   // contains U+200F RIGHT-TO-LEFT MARK
        << "dd‏/MM‏/yyyy" // contains U+200F RIGHT-TO-LEFT MARK
        << "d MMMM، y"
        << "EEEE، d MMMM، y"
        << "h:mm a"
        << "h:mm:ss a"
        << "z h:mm:ss a"
        << "zzzz h:mm:ss a";

    QTest::newRow("ja_JP, Gregorian calendar")
        << "fi_FI" // language does not matter unless lc_time is empty
        << "fi_FI" // lc_messages does not matter
        << "ja_JP" // only lc_time matters
        << MLocale::GregorianCalendar
        << "yy/MM/dd"
        << "yyyy/MM/dd"
        << "y年M月d日"
        << "y年M月d日EEEE"
        << "H:mm"
        << "H:mm:ss"
        << "H:mm:ss z"
        << "H時mm分ss秒 zzzz";

    QTest::newRow("ja_JP, Japanese calendar")
        << "fi_FI" // language does not matter unless lc_time is empty
        << "fi_FI" // lc_messages does not matter
        << "ja_JP" // only lc_time matters
        << MLocale::JapaneseCalendar
        << "Gyy/MM/dd"
        << "Gyy/MM/dd"
        << "Gy年M月d日"
        << "Gy年M月d日EEEE"
        << "H:mm"
        << "H:mm:ss"
        << "H:mm:ss z"
        << "H時mm分ss秒 zzzz";

    QTest::newRow("zh_CN, Gregorian calendar")
        << "fi_FI" // language does not matter unless lc_time is empty
        << "fi_FI" // lc_messages does not matter
        << "zh_CN" // only lc_time matters
        << MLocale::GregorianCalendar
        << "yy-M-d"
        << "yyyy-M-d"
        << "y年M月d日"
        << "y年M月d日EEEE"
        << "ah:mm"
        << "ah:mm:ss"
        << "zah时mm分ss秒"
        << "zzzzah时mm分ss秒";

    QTest::newRow("zh_CN, Chinese calendar")
        << "fi_FI" // language does not matter unless lc_time is empty
        << "fi_FI" // lc_messages does not matter
        << "zh_CN" // only lc_time matters
        << MLocale::ChineseCalendar
        << "y'x'G-Ml-d"
        << "y'x'G-Ml-d"
        << "y'x'G-Ml-d"
        << "EEEE y'x'G-Ml-d"
        << "HH:mm"
        << "HH:mm:ss"
        << "HH:mm:ss z"
        << "HH:mm:ss zzzz";

    QTest::newRow("th_TH, Gregorian calendar")
        << "fi_FI" // language does not matter unless lc_time is empty
        << "fi_FI" // lc_messages does not matter
        << "th_TH" // only lc_time matters
        << MLocale::GregorianCalendar
        << "d/M/yyyy"
        << "d MMM y"
        << "d MMMM y"
        << "EEEEที่ d MMMM G y"
        << "H:mm"
        << "H:mm:ss"
        << "H นาฬิกา m นาที ss วินาที z"
        << "H นาฬิกา m นาที ss วินาที zzzz";

    QTest::newRow("th_TH, Buddhist calendar")
        << "fi_FI" // language does not matter unless lc_time is empty
        << "fi_FI" // lc_messages does not matter
        << "th_TH" // only lc_time matters
        << MLocale::BuddhistCalendar
        << "d/M/yyyy"
        << "d MMM y"
        << "d MMMM y"
        << "EEEEที่ d MMMM G y"
        << "H:mm"
        << "H:mm:ss"
        << "H นาฬิกา m นาที ss วินาที z"
        << "H นาฬิกา m นาที ss วินาที zzzz";
}

void Ut_MCalendar::testIcuFormatString()
{
    QFETCH(QString, language);
    QFETCH(QString, lcMessages);
    QFETCH(QString, lcTime);
    QFETCH(MLocale::CalendarType, calendarType);
    QFETCH(QString, dateShortResult);
    QFETCH(QString, dateMediumResult);
    QFETCH(QString, dateLongResult);
    QFETCH(QString, dateFullResult);
    QFETCH(QString, timeShortResult);
    QFETCH(QString, timeMediumResult);
    QFETCH(QString, timeLongResult);
    QFETCH(QString, timeFullResult);

    QCOMPARE(MLocale::dataPaths(), (QStringList() << "/usr/share/meegotouch/icu"));

    MLocale locale(language);
    locale.setCategoryLocale(MLocale::MLcMessages, lcMessages);
    locale.setCategoryLocale(MLocale::MLcTime, lcTime);

    QList<QString> dateResults;
    dateResults << QString("")
                <<  dateShortResult
                <<  dateMediumResult
                <<  dateLongResult
                <<  dateFullResult;
    QList<QString> timeResults;
    timeResults << QString("")
                <<  timeShortResult
                <<  timeMediumResult
                <<  timeLongResult
                <<  timeFullResult;

    for (unsigned dateType = MLocale::DateNone; dateType <= MLocale::DateFull;
            ++dateType) {
        for (unsigned timeType = MLocale::TimeNone; timeType <= MLocale::TimeFull;
                ++timeType) {
            QString expectedResult;
            if (dateType == MLocale::DateNone && timeType == MLocale::TimeNone)
                expectedResult = QString("yyyyMMdd hh:mm a");
            else if (dateType == MLocale::DateNone)
                expectedResult = timeResults[timeType];
            else if (timeType == MLocale::TimeNone)
                expectedResult = dateResults[dateType];
            else if(locale.categoryName(MLocale::MLcTime) == "ja_JP"
                    && calendarType == MLocale::GregorianCalendar
                    && (dateType == MLocale::DateLong
                        || dateType == MLocale::DateFull))
                expectedResult = dateResults[dateType] + timeResults[timeType];
            else if(locale.categoryName(MLocale::MLcTime) == "zh_CN"
                    && calendarType == MLocale::GregorianCalendar
                    && (dateType == MLocale::DateLong
                        || dateType == MLocale::DateFull))
                expectedResult = dateResults[dateType] + timeResults[timeType];
            else if(locale.categoryName(MLocale::MLcTime) == "th_TH")
                expectedResult = dateResults[dateType] + ", " + timeResults[timeType];
            else
                expectedResult = dateResults[dateType] + ' ' + timeResults[timeType];
            QString result = locale.icuFormatString(
                static_cast<MLocale::DateType>(dateType),
                static_cast<MLocale::TimeType>(timeType),
                calendarType);
            QTextStream debugStream(stderr);
            debugStream.setCodec("UTF-8");
            debugStream << "dateType: " << dateType << " timeType: " << timeType
                        << " expectedResult: " << expectedResult << " result: " << result << "\n";
            QCOMPARE(result, expectedResult);
        }
    }
}

void Ut_MCalendar::testMLocaleCalendar_data()
{
    QTest::addColumn<MLocale::CalendarType>("cal");
    QTest::newRow("default") << MLocale::DefaultCalendar;
    QTest::newRow("gregorian") << MLocale::GregorianCalendar;
    QTest::newRow("islamic") << MLocale::IslamicCalendar;
    QTest::newRow("chinese") << MLocale::ChineseCalendar;
    QTest::newRow("islamiccivil") << MLocale::IslamicCivilCalendar;
    QTest::newRow("hebrew") << MLocale::HebrewCalendar;
    QTest::newRow("japanese") << MLocale::JapaneseCalendar;
    QTest::newRow("buddhist") << MLocale::BuddhistCalendar;
    QTest::newRow("persian") << MLocale::PersianCalendar;
    QTest::newRow("coptic") << MLocale::CopticCalendar;
    QTest::newRow("ethiopian") << MLocale::EthiopicCalendar;
}

void Ut_MCalendar::testMLocaleCalendar()
{
    MLocale *z = 0;
    // We can't test with default locale because the s_systemDefault
    // is persistent and whatever we set to default locale will be
    // kept there.
    z = new MLocale("fi");
    QVERIFY2(z->isValid(), "new MLocale() did not create a valid locale");

    QFETCH(MLocale::CalendarType, cal);

    QVERIFY2(z->calendarType() == MLocale::DefaultCalendar,
             "Constructor didn't set the default calendar");
    z->setCalendarType(cal);
    QVERIFY2(z->calendarType() == cal, "Calendar was not set properly");
    delete z;
}

void Ut_MCalendar::testMLocaleCalendarConversionsFromLocaltimeQDateTime_data()
{
    QTest::addColumn<QDateTime>("datetime");
    QTest::addColumn<QString>("localeName");
    QTest::addColumn<MLocale::CalendarType>("cal");
    QTest::addColumn<QString>("dateShortResult");
    QTest::addColumn<QString>("dateMediumResult");
    QTest::addColumn<QString>("dateLongResult");
    QTest::addColumn<QString>("dateFullResult");
    QTest::addColumn<QString>("timeShortResult");
    QTest::addColumn<QString>("timeMediumResult");
    QTest::addColumn<QString>("timeLongResult");
    QTest::addColumn<QString>("timeFullResult");

    QDate date(2008, 7, 21);
    QTime time(12, 31, 0, 0);
    QDateTime datetime(date, time, Qt::LocalTime);

    QTest::newRow("21.7.2008_fi_FI_Gregorian")
            << datetime
            << QString("fi_FI")
            << MLocale::GregorianCalendar
            << QString("21.7.2008")
            << QString("21.7.2008")
            << QString("21. heinäkuuta 2008")
            << QString("maanantai 21. heinäkuuta 2008")
            << QString("12.31")
            << QString("12.31.00")
            << QString("12.31.00 UTC+3.00")
            << QString("12.31.00 Itä-Euroopan kesäaika");
    QTest::newRow("21.7.2008_en_GB_Gregorian")
            << datetime
            << QString("en_GB")
            << MLocale::GregorianCalendar
            << QString("21/07/2008")
            << QString("21 Jul 2008")
            << QString("21 July 2008")
            << QString("Monday, 21 July 2008")
            << QString("12:31")
            << QString("12:31:00")
            << QString("12:31:00 EEST")
            << QString("12:31:00 Eastern European Summer Time");
    QTest::newRow("21.7.2008_de_DE_Gregorian")
            << datetime
            << QString("de_DE")
            << MLocale::GregorianCalendar
            << QString("21.07.08")
            << QString("21.07.2008")
            << QString("21. Juli 2008")
            << QString("Montag, 21. Juli 2008")
            << QString("12:31")
            << QString("12:31:00")
            << QString("12:31:00 GMT+03:00")
            << QString("12:31:00 Osteuropäische Sommerzeit");
    QTest::newRow("21.7.2008_nn_NO_Gregorian")
            << datetime
            << QString("nn_NO")
            << MLocale::GregorianCalendar
            << QString("21.07.08")
            << QString("21. jul. 2008")
            << QString("21. juli 2008")
            << QString("måndag 21. juli 2008")
            << QString("12:31")
            << QString("12:31:00")
            << QString("12:31:00 GMT+03:00")
            << QString("kl. 12:31:00 austeuropeisk sommartid");
    QTest::newRow("21.7.2008_nb_NO_Gregorian")
            << datetime
            << QString("nb_NO")
            << MLocale::GregorianCalendar
            << QString("21.07.08")
            << QString("21. juli 2008")
            << QString("21. juli 2008")
            << QString("mandag 21. juli 2008")
            << QString("12:31")
            << QString("12:31:00")
            << QString("12:31:00 GMT+03:00")
            << QString("kl. 12:31:00 østeuropeisk sommertid");
    QTest::newRow("21.7.2008_no_NO_Gregorian")
            << datetime
            << QString("no_NO")
            << MLocale::GregorianCalendar
            << QString("21.07.08")
            << QString("21. juli 2008")
            << QString("21. juli 2008")
            << QString("mandag 21. juli 2008")
            << QString("12:31")
            << QString("12:31:00")
            << QString("12:31:00 GMT+03:00")
            << QString("kl. 12:31:00 østeuropeisk sommertid");
}

void Ut_MCalendar::testMLocaleCalendarConversionsFromLocaltimeQDateTime()
{
    QFETCH(QDateTime, datetime);
    QFETCH(QString, localeName);
    QFETCH(MLocale::CalendarType, cal);
    QFETCH(QString, dateShortResult);
    QFETCH(QString, dateMediumResult);
    QFETCH(QString, dateLongResult);
    QFETCH(QString, dateFullResult);
    QFETCH(QString, timeShortResult);
    QFETCH(QString, timeMediumResult);
    QFETCH(QString, timeLongResult);
    QFETCH(QString, timeFullResult);

    MLocale locale(localeName);

    QList<QString> dateResults;
    dateResults << QString("")
                <<  dateShortResult
                <<  dateMediumResult
                <<  dateLongResult
                <<  dateFullResult;
    QList<QString> timeResults;
    timeResults << QString("")
                <<  timeShortResult
                <<  timeMediumResult
                <<  timeLongResult
                <<  timeFullResult;

    for (unsigned dateType = MLocale::DateNone; dateType <= MLocale::DateFull;
            ++dateType) {
        for (unsigned timeType = MLocale::TimeNone; timeType <= MLocale::TimeFull;
                ++timeType) {
            QString result;
            if (dateType == MLocale::DateNone)
                result = timeResults[timeType];
            else if (timeType == MLocale::TimeNone)
                result = dateResults[dateType];
            else
                result = dateResults[dateType] + ' ' + timeResults[timeType];
            qDebug() << "dateType" << dateType << "timeType" << timeType
                     << "result" << result;
            QCOMPARE(
                locale.formatDateTime(datetime,
                                      static_cast<MLocale::DateType>(dateType),
                                      static_cast<MLocale::TimeType>(timeType),
                                      cal),
                result);
        }
    }
}

void Ut_MCalendar::testMLocaleCalendarConversionsFromUTCQDateTime_data()
{
    QTest::addColumn<QDateTime>("datetime");
    QTest::addColumn<QString>("localeName");
    QTest::addColumn<MLocale::CalendarType>("calType");
    QTest::addColumn<QString>("short_result");
    QTest::addColumn<QString>("long_result");
    QTest::addColumn<QString>("full_result");

    QDate date(2008, 7, 21);
    QTime time(12, 31, 0, 0);
    QDateTime datetime(date, time, Qt::UTC); // finland is utc+3 so maps to 15:31

    QTest::newRow("21.7.2008_fi_FI_Gregorian")
            << datetime
            << QString("fi_FI")
            << MLocale::GregorianCalendar
            << QString("21.7.2008 15.31")
            << QString("21. heinäkuuta 2008 15.31.00 UTC+3.00")
            << QString("maanantai 21. heinäkuuta 2008 15.31.00 Itä-Euroopan kesäaika");
    QTest::newRow("21.7.2008_en_GB_Gregorian")
            << datetime
            << QString("en_GB")
            << MLocale::GregorianCalendar
            << QString("21/07/2008 15:31")
            << QString("21 July 2008 15:31:00 EEST")
            << QString("Monday, 21 July 2008 15:31:00 Eastern European Summer Time");
    QTest::newRow("21.7.2008_nn_NO_Gregorian")
            << datetime
            << QString("nn_NO")
            << MLocale::GregorianCalendar
            << QString("21.07.08 15:31")
            << QString("21. juli 2008 15:31:00 GMT+03:00")
            << QString("måndag 21. juli 2008 kl. 15:31:00 austeuropeisk sommartid");
    QTest::newRow("21.7.2008_nb_NO_Gregorian")
            << datetime
            << QString("nb_NO")
            << MLocale::GregorianCalendar
            << QString("21.07.08 15:31")
            << QString("21. juli 2008 15:31:00 GMT+03:00")
            << QString("mandag 21. juli 2008 kl. 15:31:00 østeuropeisk sommertid");
}

void Ut_MCalendar::testMLocaleCalendarConversionsFromUTCQDateTime()
{
    QFETCH(QDateTime, datetime);
    QFETCH(QString, localeName);
    QFETCH(MLocale::CalendarType, calType);
    QFETCH(QString, short_result);
    QFETCH(QString, long_result);
    QFETCH(QString, full_result);

    MLocale locale(localeName);

    QCOMPARE(locale.formatDateTime(datetime, MLocale::DateShort,
                                   MLocale::TimeShort, calType),
             short_result);
    QCOMPARE(locale.formatDateTime(datetime, MLocale::DateLong,
                                   MLocale::TimeLong, calType),
             long_result);
    QCOMPARE(locale.formatDateTime(datetime, MLocale::DateFull,
                                   MLocale::TimeFull, calType),
             full_result);
}

void Ut_MCalendar::testMLocaleCalendarConversionsFromMCalendar_data()
{
    QTest::addColumn<QString>("localeName");
    QTest::addColumn<QString>("lcMessages");
    QTest::addColumn<QString>("lcTime");
    QTest::addColumn<QString>("lcNumeric");
    QTest::addColumn<QString>("timeZone");
    QTest::addColumn<MLocale::CalendarType>("calType");
    QTest::addColumn<int>("year");
    QTest::addColumn<int>("month");
    QTest::addColumn<int>("day");
    QTest::addColumn<QString>("dateShortResult");
    QTest::addColumn<QString>("dateMediumResult");
    QTest::addColumn<QString>("dateLongResult");
    QTest::addColumn<QString>("dateFullResult");
    QTest::addColumn<QString>("timeShortResult");
    QTest::addColumn<QString>("timeMediumResult");
    QTest::addColumn<QString>("timeLongResult");
    QTest::addColumn<QString>("timeFullResult");

    QTest::newRow("21.7.2008_de_DE_Gregorian")
        << QString("fi_FI")
        << QString("fi_FI")
        << QString("de_DE") // only this matters
        << QString("fi_FI")
        << "Europe/Helsinki"
        << MLocale::GregorianCalendar
        << 2008
        << 7
        << 21
        << "21.07.08"
        << "21.07.2008"
        << "21. Juli 2008"
        << "Montag, 21. Juli 2008"
        << "14:31"
        << "14:31:00"
        << "14:31:00 GMT+03:00"
        << "14:31:00 Osteuropäische Sommerzeit";
    QTest::newRow("21.7.2008_fi_FI_Gregorian")
        << QString("de_DE")
        << QString("de_DE")
        << QString("fi_FI") // only this matters
        << QString("de_DE")
        << "Europe/Helsinki"
        << MLocale::GregorianCalendar
        << 2008
        << 7
        << 21
        << "21.7.2008"
        << "21.7.2008"
        << "21. heinäkuuta 2008"
        << "maanantai 21. heinäkuuta 2008"
        << "14.31"
        << "14.31.00"
        << "14.31.00 UTC+3.00"
        << "14.31.00 Itä-Euroopan kesäaika";
    QTest::newRow("21.7.2008_en_GB_Gregorian")
        << QString("fi_FI")
        << QString("fi_FI")
        << QString("en_GB") // only this matters
        << QString("fi_FI")
        << "Europe/Helsinki"
        << MLocale::GregorianCalendar
        << 2008
        << 7
        << 21
        << "21/07/2008"
        << "21 Jul 2008"
        << "21 July 2008"
        << "Monday, 21 July 2008"
        << "14:31"
        << "14:31:00"
        << "14:31:00 EEST"
        << "14:31:00 Eastern European Summer Time";
    QTest::newRow("21.7.2008_nn_NO_Gregorian")
        << QString("fi_FI")
        << QString("fi_FI")
        << QString("nn_NO") // only this matters
        << QString("fi_FI")
        << "Europe/Helsinki"
        << MLocale::GregorianCalendar
        << 2008
        << 7
        << 21
        << "21.07.08"
        << "21. jul. 2008"
        << "21. juli 2008"
        << "måndag 21. juli 2008"
        << "14:31"
        << "14:31:00"
        << "14:31:00 GMT+03:00"
        << "kl. 14:31:00 austeuropeisk sommartid";
    QTest::newRow("21.7.2008_nb_NO_Gregorian")
        << QString("fi_FI")
        << QString("fi_FI")
        << QString("nb_NO") // only this matters
        << QString("fi_FI")
        << "Europe/Helsinki"
        << MLocale::GregorianCalendar
        << 2008
        << 7
        << 21
        << "21.07.08"
        << "21. juli 2008"
        << "21. juli 2008"
        << "mandag 21. juli 2008"
        << "14:31"
        << "14:31:00"
        << "14:31:00 GMT+03:00"
        << "kl. 14:31:00 østeuropeisk sommertid";
    QTest::newRow("21.7.2008_no_NO_Gregorian")
        << QString("fi_FI")
        << QString("fi_FI")
        << QString("no_NO") // only this matters
        << QString("fi_FI")
        << "Europe/Helsinki"
        << MLocale::GregorianCalendar
        << 2008
        << 7
        << 21
        << "21.07.08"
        << "21. juli 2008"
        << "21. juli 2008"
        << "mandag 21. juli 2008"
        << "14:31"
        << "14:31:00"
        << "14:31:00 GMT+03:00"
        << "kl. 14:31:00 østeuropeisk sommertid";
    QTest::newRow("21.7.2008_ja_JP_Gregorian")
        << QString("fi_FI")
        << QString("fi_FI")
        << QString("ja_JP") // only this matters
        << QString("fi_FI")
        << "Europe/Helsinki"
        << MLocale::GregorianCalendar
        << 2008
        << 7
        << 21
        << "08/07/21"
        << "2008/07/21"
        << "2008年7月21日"
        << "2008年7月21日月曜日"
        << "14:31"
        << "14:31:00"
        << "14:31:00 GMT+03:00"
        << "14時31分00秒 東欧夏時間";
    QTest::newRow("21.7.2008_ja_JP_Gregorian")
        << QString("fi_FI")
        << QString("fi_FI")
        << QString("ja_JP") // only this matters
        << QString("fi_FI")
        << "Europe/Helsinki"
        << MLocale::GregorianCalendar
        << 2008
        << 7
        << 21
        << "08/07/21"
        << "2008/07/21"
        << "2008年7月21日"
        << "2008年7月21日月曜日"
        << "14:31"
        << "14:31:00"
        << "14:31:00 GMT+03:00"
        << "14時31分00秒 東欧夏時間";
    QTest::newRow("21.7.2008_zh_CN_Gregorian")
        << QString("fi_FI")
        << QString("fi_FI")
        << QString("zh_CN") // only this matters
        << QString("fi_FI")
        << "Europe/Helsinki"
        << MLocale::GregorianCalendar
        << 2008
        << 7
        << 21
        << "08-7-21"
        << "2008-7-21"
        << "2008年7月21日"
        << "2008年7月21日星期一"
        << "下午2:31"
        << "下午2:31:00"
        << "格林尼治标准时间+0300下午2时31分00秒"
        << "东欧夏令时间下午2时31分00秒";
    QTest::newRow("21.7.2008_ar_EG_Gregorian")
        << QString("fi_FI")
        << QString("fi_FI")
        << QString("ar_EG") // only this matters
        << QString("fi_FI")
        << "Europe/Helsinki"
        << MLocale::GregorianCalendar
        << 2008
        << 7
        << 21
        << "٢١‏/٧‏/٢٠٠٨"
        << "٢١‏/٠٧‏/٢٠٠٨"
        << "٢١ يوليو، ٢٠٠٨"
        << "الإثنين، ٢١ يوليو، ٢٠٠٨"
        << "٢:٣١ م"
        << "٢:٣١:٠٠ م"
        << "جرينتش+٠٣:٠٠ ٢:٣١:٠٠ م"
        << "جرينتش+٠٣:٠٠ ٢:٣١:٠٠ م";
    QTest::newRow("21.7.2008_th_TH_Gregorian")
        << QString("fi_FI")
        << QString("fi_FI")
        << QString("th_TH") // only this matters
        << QString("fi_FI")
        << "Europe/Helsinki"
        << MLocale::GregorianCalendar
        << 2008
        << 7
        << 21
        << "21/7/2008"
        << "21 ก.ค. 2008"
        << "21 กรกฎาคม 2008"
        << "วันจันทร์ที่ 21 กรกฎาคม ค.ศ. 2008"
        << "14:31"
        << "14:31:00"
        << "14 นาฬิกา 31 นาที 00 วินาที GMT+03:00"
        << "14 นาฬิกา 31 นาที 00 วินาที GMT+03:00";
}

void Ut_MCalendar::testMLocaleCalendarConversionsFromMCalendar()
{
    QFETCH(QString, localeName);
    QFETCH(QString, lcMessages);
    QFETCH(QString, lcTime);
    QFETCH(QString, lcNumeric);
    QFETCH(QString, timeZone);
    QFETCH(MLocale::CalendarType, calType);
    QFETCH(int, year);
    QFETCH(int, month);
    QFETCH(int, day);
    QFETCH(QString, dateShortResult);
    QFETCH(QString, dateMediumResult);
    QFETCH(QString, dateLongResult);
    QFETCH(QString, dateFullResult);
    QFETCH(QString, timeShortResult);
    QFETCH(QString, timeMediumResult);
    QFETCH(QString, timeLongResult);
    QFETCH(QString, timeFullResult);

    QCOMPARE(MLocale::dataPaths(), (QStringList() << "/usr/share/meegotouch/icu"));

    MLocale locale(localeName);
    locale.setCategoryLocale(MLocale::MLcMessages, lcMessages);
    locale.setCategoryLocale(MLocale::MLcTime, lcTime);
    locale.setCategoryLocale(MLocale::MLcNumeric, lcNumeric);
    MCalendar::setSystemTimeZone("Europe/Helsinki");
    MCalendar mcal(calType);
    mcal.setDate(year, month, day);
    mcal.setTime(14, 31, 0);
    QDateTime dateTime(QDate(year, month, day), QTime(14, 31, 0, 0));

    QList<QString> dateResults;
    dateResults << QString("")
                <<  dateShortResult
                <<  dateMediumResult
                <<  dateLongResult
                <<  dateFullResult;
    QList<QString> timeResults;
    timeResults << QString("")
                <<  timeShortResult
                <<  timeMediumResult
                <<  timeLongResult
                <<  timeFullResult;

    for (unsigned dateType = MLocale::DateNone; dateType <= MLocale::DateFull;
            ++dateType) {
        for (unsigned timeType = MLocale::TimeNone; timeType <= MLocale::TimeFull;
                ++timeType) {
            QString expectedResult;
            if (dateType == MLocale::DateNone)
                expectedResult = timeResults[timeType];
            else if (timeType == MLocale::TimeNone)<commit_msg>Changes: make tests in ut_mcalendar work individually<commit_after>/***************************************************************************
**
** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (<EMAIL>)
**
** This file is part of libmeegotouch.
**
** If you have questions regarding the use of this file, please contact
** Nokia at <EMAIL>.
**
** This library is free software; you can redistribute it and/or
** modify it under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation
** and appearing in the file LICENSE.LGPL included in the packaging
** of this file.
**
****************************************************************************/

#include <QCoreApplication>
#include <QTextCodec>
#include <MLocale>
#include <unicode/uversion.h>

#include "ut_mcalendar.h"

void Ut_MCalendar::initTestCase()
{
    static int argc = 0;
    static char *argv[1] = { (char *) "" };
    qap = new QCoreApplication(argc, argv);
    QTextCodec::setCodecForCStrings(QTextCodec::codecForName("UTF-8"));
    QProcess process;
    process.start("sh -c \"dpkg -s libicu44 | grep Version | perl -pe 's/^Version:[[:space:]]*([^[[:space:]]+)$/$1/g'\"");
    if (!process.waitForFinished()) {
        qDebug() << "cannot run process to check libicu44 package version , exiting ...";
        exit(1);
    }
    icuPackageVersion = process.readAllStandardOutput();
    icuPackageVersion.replace("\n", "");
    qDebug() << "libicu44 package version is:" << icuPackageVersion;
}

void Ut_MCalendar::cleanupTestCase()
{
    delete qap;
}

void Ut_MCalendar::init()
{
    // most tests use the Finnish timezone:
    MCalendar::setSystemTimeZone("Europe/Helsinki");
}

void Ut_MCalendar::cleanup()
{
}

void Ut_MCalendar::testTimeZones()
{
    qDebug() << "systemTimeZone() =" << MCalendar::systemTimeZone();
    MCalendar::setSystemTimeZone("Europe/Helsinki");
    QCOMPARE(MCalendar::systemTimeZone(), QString("Europe/Helsinki"));
    foreach (QString timeZone, MCalendar::supportedTimeZones()) {
        MCalendar::setSystemTimeZone(timeZone);
        QCOMPARE(MCalendar::systemTimeZone(), timeZone);
    }
}

void Ut_MCalendar::testTimeZonesInCountry_data()
{
    QTest::addColumn<QString>("countryCode");
    QTest::addColumn<QStringList>("timeZoneList");

    QTest::newRow("FI")
        << "FI"
        << (QStringList() << "Europe/Helsinki");
    QTest::newRow("JP")
        << "JP"
        << (QStringList() << "Asia/Tokyo" << "JST" << "Japan");
}

void Ut_MCalendar::testTimeZonesInCountry()
{
    QFETCH(QString, countryCode);
    QFETCH(QStringList, timeZoneList);
    QCOMPARE(MCalendar::supportedTimeZones(countryCode), timeZoneList);
}

void Ut_MCalendar::testConversionFromAndToQDateTime_data()
{
    QTest::addColumn<QDate>("qDate");
    QTest::addColumn<QTime>("qTime");
    QTest::addColumn<int>("qTimeSpec");
    QTest::addColumn<QString>("timeZone");

    QTest::newRow("1945-07-21 Qt::Localtime UTC")
            << QDate(1945, 7, 31)
            << QTime(14, 31, 0, 0)
            << (int) Qt::LocalTime
            << "UTC";

    QTest::newRow("1963-07-21 Qt::Localtime UTC")
            << QDate(1963, 7, 31)
            << QTime(14, 31, 0, 0)
            << (int) Qt::LocalTime
            << "UTC";

    QTest::newRow("2040-07-21 Qt::Localtime UTC")
            << QDate(2040, 7, 31)
            << QTime(14, 31, 0, 0)
            << (int) Qt::LocalTime
            << "UTC";

    QTest::newRow("2050-07-21 Qt::Localtime UTC")
            << QDate(2050, 7, 31)
            << QTime(14, 31, 0, 0)
            << (int) Qt::LocalTime
            << "UTC";

    QTest::newRow("2068-07-21 Qt::Localtime UTC")
            << QDate(2068, 7, 31)
            << QTime(14, 31, 0, 0)
            << (int) Qt::LocalTime
            << "UTC";

    QTest::newRow("2008-07-21 Qt::Localtime UTC")
            << QDate(2008, 7, 21)
            << QTime(12, 31, 0, 0)
            << (int) Qt::LocalTime
            << "UTC";

    QTest::newRow("2008-07-21 Qt::UTC UTC")
            << QDate(2008, 7, 21)
            << QTime(12, 31, 0, 0)
            << (int) Qt::UTC
            << "UTC";

    QTest::newRow("2008-07-21 Qt::LocalTime Europe/Helsinki")
            << QDate(2008, 7, 21)
            << QTime(12, 31, 0, 0)
            << (int) Qt::LocalTime
            << "Europe/Helsinki";

    QTest::newRow("2008-07-21 Qt::UTC Europe/Helsinki")
            << QDate(2008, 7, 21)
            << QTime(12, 31, 0, 0)
            << (int) Qt::UTC
            << "Europe/Helsinki";
}

void Ut_MCalendar::testConversionFromAndToQDateTime()
{
    QFETCH(QDate, qDate);
    QFETCH(QTime, qTime);
    QFETCH(int, qTimeSpec);
    QFETCH(QString, timeZone);

    MCalendar::setSystemTimeZone(timeZone);

    MCalendar mcal;
    QDateTime datetime(qDate, qTime, (Qt::TimeSpec) qTimeSpec);
    mcal.setDateTime(datetime);
    QCOMPARE(mcal.qDateTime((Qt::TimeSpec) qTimeSpec), datetime);
}

void Ut_MCalendar::testIcuFormatString_data()
{
    QTest::addColumn<QString>("language");
    QTest::addColumn<QString>("lcMessages");
    QTest::addColumn<QString>("lcTime");
    QTest::addColumn<MLocale::CalendarType>("calendarType");
    QTest::addColumn<QString>("dateShortResult");
    QTest::addColumn<QString>("dateMediumResult");
    QTest::addColumn<QString>("dateLongResult");
    QTest::addColumn<QString>("dateFullResult");
    QTest::addColumn<QString>("timeShortResult");
    QTest::addColumn<QString>("timeMediumResult");
    QTest::addColumn<QString>("timeLongResult");
    QTest::addColumn<QString>("timeFullResult");

    QTest::newRow("de_DE, Gregorian calendar")
        << "fi_FI" // language does not matter unless lc_time is empty
        << "fi_FI" // lc_messages does not matter
        << "de_DE" // only lc_time matters
        << MLocale::GregorianCalendar
        << "dd.MM.yy"
        << "dd.MM.yyyy"
        << "d. MMMM y"
        << "EEEE, d. MMMM y"
        << "HH:mm"
        << "HH:mm:ss"
        << "HH:mm:ss z"
        << "HH:mm:ss zzzz";

    QTest::newRow("fi_FI, Gregorian calendar")
        << "de_DE" // language does not matter unless lc_time is empty
        << "de_DE" // lc_messages does not matter
        << "fi_FI" // only lc_time matters
        << MLocale::GregorianCalendar
        << "d.M.yyyy"
        << "d.M.yyyy"
        << "d. MMMM y"
        << "cccc d. MMMM y"
        << "H.mm"
        << "H.mm.ss"
        << "H.mm.ss z"
        << "H.mm.ss zzzz";

    QTest::newRow("fi_FI, Gregorian calendar")
        << "fi_FI" // language does not matter unless lc_time is empty
        << "de_DE" // lc_messages does not matter
        << "" // only lc_time matters
        << MLocale::GregorianCalendar
        << "d.M.yyyy"
        << "d.M.yyyy"
        << "d. MMMM y"
        << "cccc d. MMMM y"
        << "H.mm"
        << "H.mm.ss"
        << "H.mm.ss z"
        << "H.mm.ss zzzz";

    QTest::newRow("fi_FI, Islamic calendar")
        << "fi_FI" // language does not matter unless lc_time is empty
        << "de_DE" // lc_messages does not matter
        << "" // only lc_time matters
        << MLocale::IslamicCalendar
        << "d.M.yyyy"
        << "d.M.yyyy"
        << "d. MMMM y"
        << "cccc d. MMMM y"
        << "H.mm"
        << "H.mm.ss"
        << "H.mm.ss z"
        << "H.mm.ss zzzz";

    QTest::newRow("Arabic, Gregorian calendar")
        << "fi_FI" // language does not matter unless lc_time is empty
        << "de_DE" // lc_messages does not matter
        << "ar_EG" // only lc_time matters
        << MLocale::GregorianCalendar
        << "d‏/M‏/yyyy"   // contains U+200F RIGHT-TO-LEFT MARK
        << "dd‏/MM‏/yyyy" // contains U+200F RIGHT-TO-LEFT MARK
        << "d MMMM، y"
        << "EEEE، d MMMM، y"
        << "h:mm a"
        << "h:mm:ss a"
        << "z h:mm:ss a"
        << "zzzz h:mm:ss a";

    QTest::newRow("Arabic, Islamic calendar")
        << "fi_FI" // language does not matter unless lc_time is empty
        << "de_DE" // lc_messages does not matter
        << "ar_EG" // only lc_time matters
        << MLocale::IslamicCalendar
        << "d‏/M‏/yyyy"   // contains U+200F RIGHT-TO-LEFT MARK
        << "dd‏/MM‏/yyyy" // contains U+200F RIGHT-TO-LEFT MARK
        << "d MMMM، y"
        << "EEEE، d MMMM، y"
        << "h:mm a"
        << "h:mm:ss a"
        << "z h:mm:ss a"
        << "zzzz h:mm:ss a";

    QTest::newRow("ja_JP, Gregorian calendar")
        << "fi_FI" // language does not matter unless lc_time is empty
        << "fi_FI" // lc_messages does not matter
        << "ja_JP" // only lc_time matters
        << MLocale::GregorianCalendar
        << "yy/MM/dd"
        << "yyyy/MM/dd"
        << "y年M月d日"
        << "y年M月d日EEEE"
        << "H:mm"
        << "H:mm:ss"
        << "H:mm:ss z"
        << "H時mm分ss秒 zzzz";

    QTest::newRow("ja_JP, Japanese calendar")
        << "fi_FI" // language does not matter unless lc_time is empty
        << "fi_FI" // lc_messages does not matter
        << "ja_JP" // only lc_time matters
        << MLocale::JapaneseCalendar
        << "Gyy/MM/dd"
        << "Gyy/MM/dd"
        << "Gy年M月d日"
        << "Gy年M月d日EEEE"
        << "H:mm"
        << "H:mm:ss"
        << "H:mm:ss z"
        << "H時mm分ss秒 zzzz";

    QTest::newRow("zh_CN, Gregorian calendar")
        << "fi_FI" // language does not matter unless lc_time is empty
        << "fi_FI" // lc_messages does not matter
        << "zh_CN" // only lc_time matters
        << MLocale::GregorianCalendar
        << "yy-M-d"
        << "yyyy-M-d"
        << "y年M月d日"
        << "y年M月d日EEEE"
        << "ah:mm"
        << "ah:mm:ss"
        << "zah时mm分ss秒"
        << "zzzzah时mm分ss秒";

    QTest::newRow("zh_CN, Chinese calendar")
        << "fi_FI" // language does not matter unless lc_time is empty
        << "fi_FI" // lc_messages does not matter
        << "zh_CN" // only lc_time matters
        << MLocale::ChineseCalendar
        << "y'x'G-Ml-d"
        << "y'x'G-Ml-d"
        << "y'x'G-Ml-d"
        << "EEEE y'x'G-Ml-d"
        << "HH:mm"
        << "HH:mm:ss"
        << "HH:mm:ss z"
        << "HH:mm:ss zzzz";

    QTest::newRow("th_TH, Gregorian calendar")
        << "fi_FI" // language does not matter unless lc_time is empty
        << "fi_FI" // lc_messages does not matter
        << "th_TH" // only lc_time matters
        << MLocale::GregorianCalendar
        << "d/M/yyyy"
        << "d MMM y"
        << "d MMMM y"
        << "EEEEที่ d MMMM G y"
        << "H:mm"
        << "H:mm:ss"
        << "H นาฬิกา m นาที ss วินาที z"
        << "H นาฬิกา m นาที ss วินาที zzzz";

    QTest::newRow("th_TH, Buddhist calendar")
        << "fi_FI" // language does not matter unless lc_time is empty
        << "fi_FI" // lc_messages does not matter
        << "th_TH" // only lc_time matters
        << MLocale::BuddhistCalendar
        << "d/M/yyyy"
        << "d MMM y"
        << "d MMMM y"
        << "EEEEที่ d MMMM G y"
        << "H:mm"
        << "H:mm:ss"
        << "H นาฬิกา m นาที ss วินาที z"
        << "H นาฬิกา m นาที ss วินาที zzzz";
}

void Ut_MCalendar::testIcuFormatString()
{
    QFETCH(QString, language);
    QFETCH(QString, lcMessages);
    QFETCH(QString, lcTime);
    QFETCH(MLocale::CalendarType, calendarType);
    QFETCH(QString, dateShortResult);
    QFETCH(QString, dateMediumResult);
    QFETCH(QString, dateLongResult);
    QFETCH(QString, dateFullResult);
    QFETCH(QString, timeShortResult);
    QFETCH(QString, timeMediumResult);
    QFETCH(QString, timeLongResult);
    QFETCH(QString, timeFullResult);

    MLocale locale(language);
    QCOMPARE(MLocale::dataPaths(), (QStringList() << "/usr/share/meegotouch/icu"));
    locale.setCategoryLocale(MLocale::MLcMessages, lcMessages);
    locale.setCategoryLocale(MLocale::MLcTime, lcTime);

    QList<QString> dateResults;
    dateResults << QString("")
                <<  dateShortResult
                <<  dateMediumResult
                <<  dateLongResult
                <<  dateFullResult;
    QList<QString> timeResults;
    timeResults << QString("")
                <<  timeShortResult
                <<  timeMediumResult
                <<  timeLongResult
                <<  timeFullResult;

    for (unsigned dateType = MLocale::DateNone; dateType <= MLocale::DateFull;
            ++dateType) {
        for (unsigned timeType = MLocale::TimeNone; timeType <= MLocale::TimeFull;
                ++timeType) {
            QString expectedResult;
            if (dateType == MLocale::DateNone && timeType == MLocale::TimeNone)
                expectedResult = QString("yyyyMMdd hh:mm a");
            else if (dateType == MLocale::DateNone)
                expectedResult = timeResults[timeType];
            else if (timeType == MLocale::TimeNone)
                expectedResult = dateResults[dateType];
            else if(locale.categoryName(MLocale::MLcTime) == "ja_JP"
                    && calendarType == MLocale::GregorianCalendar
                    && (dateType == MLocale::DateLong
                        || dateType == MLocale::DateFull))
                expectedResult = dateResults[dateType] + timeResults[timeType];
            else if(locale.categoryName(MLocale::MLcTime) == "zh_CN"
                    && calendarType == MLocale::GregorianCalendar
                    && (dateType == MLocale::DateLong
                        || dateType == MLocale::DateFull))
                expectedResult = dateResults[dateType] + timeResults[timeType];
            else if(locale.categoryName(MLocale::MLcTime) == "th_TH")
                expectedResult = dateResults[dateType] + ", " + timeResults[timeType];
            else
                expectedResult = dateResults[dateType] + ' ' + timeResults[timeType];
            QString result = locale.icuFormatString(
                static_cast<MLocale::DateType>(dateType),
                static_cast<MLocale::TimeType>(timeType),
                calendarType);
            QTextStream debugStream(stderr);
            debugStream.setCodec("UTF-8");
            debugStream << "dateType: " << dateType << " timeType: " << timeType
                        << " expectedResult: " << expectedResult << " result: " << result << "\n";
            QCOMPARE(result, expectedResult);
        }
    }
}

void Ut_MCalendar::testMLocaleCalendar_data()
{
    QTest::addColumn<MLocale::CalendarType>("cal");
    QTest::newRow("default") << MLocale::DefaultCalendar;
    QTest::newRow("gregorian") << MLocale::GregorianCalendar;
    QTest::newRow("islamic") << MLocale::IslamicCalendar;
    QTest::newRow("chinese") << MLocale::ChineseCalendar;
    QTest::newRow("islamiccivil") << MLocale::IslamicCivilCalendar;
    QTest::newRow("hebrew") << MLocale::HebrewCalendar;
    QTest::newRow("japanese") << MLocale::JapaneseCalendar;
    QTest::newRow("buddhist") << MLocale::BuddhistCalendar;
    QTest::newRow("persian") << MLocale::PersianCalendar;
    QTest::newRow("coptic") << MLocale::CopticCalendar;
    QTest::newRow("ethiopian") << MLocale::EthiopicCalendar;
}

void Ut_MCalendar::testMLocaleCalendar()
{
    MLocale *z = 0;
    // We can't test with default locale because the s_systemDefault
    // is persistent and whatever we set to default locale will be
    // kept there.
    z = new MLocale("fi");
    QVERIFY2(z->isValid(), "new MLocale() did not create a valid locale");

    QFETCH(MLocale::CalendarType, cal);

    QVERIFY2(z->calendarType() == MLocale::DefaultCalendar,
             "Constructor didn't set the default calendar");
    z->setCalendarType(cal);
    QVERIFY2(z->calendarType() == cal, "Calendar was not set properly");
    delete z;
}

void Ut_MCalendar::testMLocaleCalendarConversionsFromLocaltimeQDateTime_data()
{
    QTest::addColumn<QDateTime>("datetime");
    QTest::addColumn<QString>("localeName");
    QTest::addColumn<MLocale::CalendarType>("cal");
    QTest::addColumn<QString>("dateShortResult");
    QTest::addColumn<QString>("dateMediumResult");
    QTest::addColumn<QString>("dateLongResult");
    QTest::addColumn<QString>("dateFullResult");
    QTest::addColumn<QString>("timeShortResult");
    QTest::addColumn<QString>("timeMediumResult");
    QTest::addColumn<QString>("timeLongResult");
    QTest::addColumn<QString>("timeFullResult");

    QDate date(2008, 7, 21);
    QTime time(12, 31, 0, 0);
    QDateTime datetime(date, time, Qt::LocalTime);

    QTest::newRow("21.7.2008_fi_FI_Gregorian")
            << datetime
            << QString("fi_FI")
            << MLocale::GregorianCalendar
            << QString("21.7.2008")
            << QString("21.7.2008")
            << QString("21. heinäkuuta 2008")
            << QString("maanantai 21. heinäkuuta 2008")
            << QString("12.31")
            << QString("12.31.00")
            << QString("12.31.00 UTC+3.00")
            << QString("12.31.00 Itä-Euroopan kesäaika");
    QTest::newRow("21.7.2008_en_GB_Gregorian")
            << datetime
            << QString("en_GB")
            << MLocale::GregorianCalendar
            << QString("21/07/2008")
            << QString("21 Jul 2008")
            << QString("21 July 2008")
            << QString("Monday, 21 July 2008")
            << QString("12:31")
            << QString("12:31:00")
            << QString("12:31:00 EEST")
            << QString("12:31:00 Eastern European Summer Time");
    QTest::newRow("21.7.2008_de_DE_Gregorian")
            << datetime
            << QString("de_DE")
            << MLocale::GregorianCalendar
            << QString("21.07.08")
            << QString("21.07.2008")
            << QString("21. Juli 2008")
            << QString("Montag, 21. Juli 2008")
            << QString("12:31")
            << QString("12:31:00")
            << QString("12:31:00 GMT+03:00")
            << QString("12:31:00 Osteuropäische Sommerzeit");
    QTest::newRow("21.7.2008_nn_NO_Gregorian")
            << datetime
            << QString("nn_NO")
            << MLocale::GregorianCalendar
            << QString("21.07.08")
            << QString("21. jul. 2008")
            << QString("21. juli 2008")
            << QString("måndag 21. juli 2008")
            << QString("12:31")
            << QString("12:31:00")
            << QString("12:31:00 GMT+03:00")
            << QString("kl. 12:31:00 austeuropeisk sommartid");
    QTest::newRow("21.7.2008_nb_NO_Gregorian")
            << datetime
            << QString("nb_NO")
            << MLocale::GregorianCalendar
            << QString("21.07.08")
            << QString("21. juli 2008")
            << QString("21. juli 2008")
            << QString("mandag 21. juli 2008")
            << QString("12:31")
            << QString("12:31:00")
            << QString("12:31:00 GMT+03:00")
            << QString("kl. 12:31:00 østeuropeisk sommertid");
    QTest::newRow("21.7.2008_no_NO_Gregorian")
            << datetime
            << QString("no_NO")
            << MLocale::GregorianCalendar
            << QString("21.07.08")
            << QString("21. juli 2008")
            << QString("21. juli 2008")
            << QString("mandag 21. juli 2008")
            << QString("12:31")
            << QString("12:31:00")
            << QString("12:31:00 GMT+03:00")
            << QString("kl. 12:31:00 østeuropeisk sommertid");
}

void Ut_MCalendar::testMLocaleCalendarConversionsFromLocaltimeQDateTime()
{
    QFETCH(QDateTime, datetime);
    QFETCH(QString, localeName);
    QFETCH(MLocale::CalendarType, cal);
    QFETCH(QString, dateShortResult);
    QFETCH(QString, dateMediumResult);
    QFETCH(QString, dateLongResult);
    QFETCH(QString, dateFullResult);
    QFETCH(QString, timeShortResult);
    QFETCH(QString, timeMediumResult);
    QFETCH(QString, timeLongResult);
    QFETCH(QString, timeFullResult);

    MLocale locale(localeName);

    QList<QString> dateResults;
    dateResults << QString("")
                <<  dateShortResult
                <<  dateMediumResult
                <<  dateLongResult
                <<  dateFullResult;
    QList<QString> timeResults;
    timeResults << QString("")
                <<  timeShortResult
                <<  timeMediumResult
                <<  timeLongResult
                <<  timeFullResult;

    for (unsigned dateType = MLocale::DateNone; dateType <= MLocale::DateFull;
            ++dateType) {
        for (unsigned timeType = MLocale::TimeNone; timeType <= MLocale::TimeFull;
                ++timeType) {
            QString result;
            if (dateType == MLocale::DateNone)
                result = timeResults[timeType];
            else if (timeType == MLocale::TimeNone)
                result = dateResults[dateType];
            else
                result = dateResults[dateType] + ' ' + timeResults[timeType];
            qDebug() << "dateType" << dateType << "timeType" << timeType
                     << "result" << result;
            QCOMPARE(
                locale.formatDateTime(datetime,
                                      static_cast<MLocale::DateType>(dateType),
                                      static_cast<MLocale::TimeType>(timeType),
                                      cal),
                result);
        }
    }
}

void Ut_MCalendar::testMLocaleCalendarConversionsFromUTCQDateTime_data()
{
    QTest::addColumn<QDateTime>("datetime");
    QTest::addColumn<QString>("localeName");
    QTest::addColumn<MLocale::CalendarType>("calType");
    QTest::addColumn<QString>("short_result");
    QTest::addColumn<QString>("long_result");
    QTest::addColumn<QString>("full_result");

    QDate date(2008, 7, 21);
    QTime time(12, 31, 0, 0);
    QDateTime datetime(date, time, Qt::UTC); // finland is utc+3 so maps to 15:31

    QTest::newRow("21.7.2008_fi_FI_Gregorian")
            << datetime
            << QString("fi_FI")
            << MLocale::GregorianCalendar
            << QString("21.7.2008 15.31")
            << QString("21. heinäkuuta 2008 15.31.00 UTC+3.00")
            << QString("maanantai 21. heinäkuuta 2008 15.31.00 Itä-Euroopan kesäaika");
    QTest::newRow("21.7.2008_en_GB_Gregorian")
            << datetime
            << QString("en_GB")
            << MLocale::GregorianCalendar
            << QString("21/07/2008 15:31")
            << QString("21 July 2008 15:31:00 EEST")
            << QString("Monday, 21 July 2008 15:31:00 Eastern European Summer Time");
    QTest::newRow("21.7.2008_nn_NO_Gregorian")
            << datetime
            << QString("nn_NO")
            << MLocale::GregorianCalendar
            << QString("21.07.08 15:31")
            << QString("21. juli 2008 15:31:00 GMT+03:00")
            << QString("måndag 21. juli 2008 kl. 15:31:00 austeuropeisk sommartid");
    QTest::newRow("21.7.2008_nb_NO_Gregorian")
            << datetime
            << QString("nb_NO")
            << MLocale::GregorianCalendar
            << QString("21.07.08 15:31")
            << QString("21. juli 2008 15:31:00 GMT+03:00")
            << QString("mandag 21. juli 2008 kl. 15:31:00 østeuropeisk sommertid");
}

void Ut_MCalendar::testMLocaleCalendarConversionsFromUTCQDateTime()
{
    QFETCH(QDateTime, datetime);
    QFETCH(QString, localeName);
    QFETCH(MLocale::CalendarType, calType);
    QFETCH(QString, short_result);
    QFETCH(QString, long_result);
    QFETCH(QString, full_result);

    MLocale locale(localeName);

    QCOMPARE(locale.formatDateTime(datetime, MLocale::DateShort,
                                   MLocale::TimeShort, calType),
             short_result);
    QCOMPARE(locale.formatDateTime(datetime, MLocale::DateLong,
                                   MLocale::TimeLong, calType),
             long_result);
    QCOMPARE(locale.formatDateTime(datetime, MLocale::DateFull,
                                   MLocale::TimeFull, calType),
             full_result);
}

void Ut_MCalendar::testMLocaleCalendarConversionsFromMCalendar_data()
{
    QTest::addColumn<QString>("localeName");
    QTest::addColumn<QString>("lcMessages");
    QTest::addColumn<QString>("lcTime");
    QTest::addColumn<QString>("lcNumeric");
    QTest::addColumn<QString>("timeZone");
    QTest::addColumn<MLocale::CalendarType>("calType");
    QTest::addColumn<int>("year");
    QTest::addColumn<int>("month");
    QTest::addColumn<int>("day");
    QTest::addColumn<QString>("dateShortResult");
    QTest::addColumn<QString>("dateMediumResult");
    QTest::addColumn<QString>("dateLongResult");
    QTest::addColumn<QString>("dateFullResult");
    QTest::addColumn<QString>("timeShortResult");
    QTest::addColumn<QString>("timeMediumResult");
    QTest::addColumn<QString>("timeLongResult");
    QTest::addColumn<QString>("timeFullResult");

    QTest::newRow("21.7.2008_de_DE_Gregorian")
        << QString("fi_FI")
        << QString("fi_FI")
        << QString("de_DE") // only this matters
        << QString("fi_FI")
        << "Europe/Helsinki"
        << MLocale::GregorianCalendar
        << 2008
        << 7
        << 21
        << "21.07.08"
        << "21.07.2008"
        << "21. Juli 2008"
        << "Montag, 21. Juli 2008"
        << "14:31"
        << "14:31:00"
        << "14:31:00 GMT+03:00"
        << "14:31:00 Osteuropäische Sommerzeit";
    QTest::newRow("21.7.2008_fi_FI_Gregorian")
        << QString("de_DE")
        << QString("de_DE")
        << QString("fi_FI") // only this matters
        << QString("de_DE")
        << "Europe/Helsinki"
        << MLocale::GregorianCalendar
        << 2008
        << 7
        << 21
        << "21.7.2008"
        << "21.7.2008"
        << "21. heinäkuuta 2008"
        << "maanantai 21. heinäkuuta 2008"
        << "14.31"
        << "14.31.00"
        << "14.31.00 UTC+3.00"
        << "14.31.00 Itä-Euroopan kesäaika";
    QTest::newRow("21.7.2008_en_GB_Gregorian")
        << QString("fi_FI")
        << QString("fi_FI")
        << QString("en_GB") // only this matters
        << QString("fi_FI")
        << "Europe/Helsinki"
        << MLocale::GregorianCalendar
        << 2008
        << 7
        << 21
        << "21/07/2008"
        << "21 Jul 2008"
        << "21 July 2008"
        << "Monday, 21 July 2008"
        << "14:31"
        << "14:31:00"
        << "14:31:00 EEST"
        << "14:31:00 Eastern European Summer Time";
    QTest::newRow("21.7.2008_nn_NO_Gregorian")
        << QString("fi_FI")
        << QString("fi_FI")
        << QString("nn_NO") // only this matters
        << QString("fi_FI")
        << "Europe/Helsinki"
        << MLocale::GregorianCalendar
        << 2008
        << 7
        << 21
        << "21.07.08"
        << "21. jul. 2008"
        << "21. juli 2008"
        << "måndag 21. juli 2008"
        << "14:31"
        << "14:31:00"
        << "14:31:00 GMT+03:00"
        << "kl. 14:31:00 austeuropeisk sommartid";
    QTest::newRow("21.7.2008_nb_NO_Gregorian")
        << QString("fi_FI")
        << QString("fi_FI")
        << QString("nb_NO") // only this matters
        << QString("fi_FI")
        << "Europe/Helsinki"
        << MLocale::GregorianCalendar
        << 2008
        << 7
        << 21
        << "21.07.08"
        << "21. juli 2008"
        << "21. juli 2008"
        << "mandag 21. juli 2008"
        << "14:31"
        << "14:31:00"
        << "14:31:00 GMT+03:00"
        << "kl. 14:31:00 østeuropeisk sommertid";
    QTest::newRow("21.7.2008_no_NO_Gregorian")
        << QString("fi_FI")
        << QString("fi_FI")
        << QString("no_NO") // only this matters
        << QString("fi_FI")
        << "Europe/Helsinki"
        << MLocale::GregorianCalendar
        << 2008
        << 7
        << 21
        << "21.07.08"
        << "21. juli 2008"
        << "21. juli 2008"
        << "mandag 21. juli 2008"
        << "14:31"
        << "14:31:00"
        << "14:31:00 GMT+03:00"
        << "kl. 14:31:00 østeuropeisk sommertid";
    QTest::newRow("21.7.2008_ja_JP_Gregorian")
        << QString("fi_FI")
        << QString("fi_FI")
        << QString("ja_JP") // only this matters
        << QString("fi_FI")
        << "Europe/Helsinki"
        << MLocale::GregorianCalendar
        << 2008
        << 7
        << 21
        << "08/07/21"
        << "2008/07/21"
        << "2008年7月21日"
        << "2008年7月21日月曜日"
        << "14:31"
        << "14:31:00"
        << "14:31:00 GMT+03:00"
        << "14時31分00秒 東欧夏時間";
    QTest::newRow("21.7.2008_ja_JP_Gregorian")
        << QString("fi_FI")
        << QString("fi_FI")
        << QString("ja_JP") // only this matters
        << QString("fi_FI")
        << "Europe/Helsinki"
        << MLocale::GregorianCalendar
        << 2008
        << 7
        << 21
        << "08/07/21"
        << "2008/07/21"
        << "2008年7月21日"
        << "2008年7月21日月曜日"
        << "14:31"
        << "14:31:00"
        << "14:31:00 GMT+03:00"
        << "14時31分00秒 東欧夏時間";
    QTest::newRow("21.7.2008_zh_CN_Gregorian")
        << QString("fi_FI")
        << QString("fi_FI")
        << QString("zh_CN") // only this matters
        << QString("fi_FI")
        << "Europe/Helsinki"
        << MLocale::GregorianCalendar
        << 2008
        << 7
        << 21
        << "08-7-21"
        << "2008-7-21"
        << "2008年7月21日"
        << "2008年7月21日星期一"
        << "下午2:31"
        << "下午2:31:00"
        << "格林尼治标准时间+0300下午2时31分00秒"
        << "东欧夏令时间下午2时31分00秒";
    QTest::newRow("21.7.2008_ar_EG_Gregorian")
        << QString("fi_FI")
        << QString("fi_FI")
        << QString("ar_EG") // only this matters
        << QString("fi_FI")
        << "Europe/Helsinki"
        << MLocale::GregorianCalendar
        << 2008
        << 7
        << 21
        << "٢١‏/٧‏/٢٠٠٨"
        << "٢١‏/٠٧‏/٢٠٠٨"
        << "٢١ يوليو، ٢٠٠٨"
        << "الإثنين، ٢١ يوليو، ٢٠٠٨"
        << "٢:٣١ م"
        << "٢:٣١:٠٠ م"
        << "جرينتش+٠٣:٠٠ ٢:٣١:٠٠ م"
        << "جرينتش+٠٣:٠٠ ٢:٣١:٠٠ م";
    QTest::newRow("21.7.2008_th_TH_Gregorian")
        << QString("fi_FI")
        << QString("fi_FI")
        << QString("th_TH") // only this matters
        << QString("fi_FI")
        << "Europe/Helsinki"
        << MLocale::GregorianCalendar
        << 2008
        << 7
        << 21
        << "21/7/2008"
        << "21 ก.ค. 2008"
        << "21 กรกฎาคม 2008"
        << "วันจันทร์ที่ 21 กรกฎาคม ค.ศ. 2008"
        << "14:31"
        << "14:31:00"
        << "14 นาฬิกา 31 นาที 00 วินาที GMT+03:00"
        << "14 นาฬิกา 31 นาที 00 วินาที GMT+03:00";
}

void Ut_MCalendar::testMLocaleCalendarConversionsFromMCalendar()
{
    QFETCH(QString, localeName);
    QFETCH(QString, lcMessages);
    QFETCH(QString, lcTime);
    QFETCH(QString, lcNumeric);
    QFETCH(QString, timeZone);
    QFETCH(MLocale::CalendarType, calType);
    QFETCH(int, year);
    QFETCH(int, month);
    QFETCH(int, day);
    QFETCH(QString, dateShortResult);
    QFETCH(QString, dateMediumResult);
    QFETCH(QString, dateLongResult);
    QFETCH(QString, dateFullResult);
    QFETCH(QString, timeShortResult);
    QFETCH(QString, timeMediumResult);
    QFETCH(QString, timeLongResult);
    QFETCH(QString, timeFullResult);

    MLocale locale(localeName);
    QCOMPARE(MLocale::dataPaths(), (QStringList() << "/usr/share/meegotouch/icu"));
    locale.setCategoryLocale(MLocale::MLcMessages, lcMessages);
    locale.setCategoryLocale(MLocale::MLcTime, lcTime);
    locale.setCategoryLocale(MLocale::MLcNumeric, lcNumeric);
    MCalendar::setSystemTimeZone("Europe/Helsinki");
    MCalendar mcal(calType);
    mcal.setDate(year, month, day);
    mcal.setTime(14, 31, 0);
    QDateTime dateTime(QDate(year, month, day), QTime(14, 31, 0, 0));

    QList<QString> dateResults;
    dateResults << QString("")
                <<  dateShortResult
                <<  dateMediumResult
                <<  dateLongResult
                <<  dateFullResult;
    QList<QString> timeResults;
    timeResults << QString("")
                <<  timeShortResult
                <<  timeMediumResult
                <<  timeLongResult
                <<  timeFullResult;

    for (unsigned dateType = MLocale::DateNone; dateType <= MLocale::DateFull;
            ++dateType) {
        for (unsigned timeType = MLocale::TimeNone; timeType <= MLocale::TimeFull;
                ++timeType) {
            QString expectedResult;
            if (dateType == MLocale::DateNone)
                expectedResult = timeResults[timeType];
            else if (timeType == MLocale::TimeNone)
{'fraction_non_alphanumeric': 0.1619886117472303, 'fraction_numerical': 0.04657424026737637, 'mean_word_length': 2.2854964160439226, 'pattern_counts': {'":': 0, '<': 2265, '<?xml version=': 0, '>': 149, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 12, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5983640', 'n_tokens_mistral': 24161, 'n_tokens_neox': 21797, 'n_words': 3767}