diff options
Diffstat (limited to 'tests/auto/corelib/time/qcalendar/tst_qcalendar.cpp')
-rw-r--r-- | tests/auto/corelib/time/qcalendar/tst_qcalendar.cpp | 236 |
1 files changed, 236 insertions, 0 deletions
diff --git a/tests/auto/corelib/time/qcalendar/tst_qcalendar.cpp b/tests/auto/corelib/time/qcalendar/tst_qcalendar.cpp new file mode 100644 index 0000000000..9b41014394 --- /dev/null +++ b/tests/auto/corelib/time/qcalendar/tst_qcalendar.cpp @@ -0,0 +1,236 @@ +/**************************************************************************** +** +** Copyright (C) 2018 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:GPL-EXCEPT$ +** Commercial License Usage +** Licensees holding valid commercial Qt licenses may use this file in +** accordance with the commercial license agreement provided with the +** Software or, alternatively, in accordance with the terms contained in +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see https://www.qt.io/terms-conditions. For further +** information use the contact form at https://www.qt.io/contact-us. +** +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 3 as published by the Free Software +** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT +** included in the packaging of this file. Please review the following +** information to ensure the GNU General Public License requirements will +** be met: https://www.gnu.org/licenses/gpl-3.0.html. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include <QtTest/QtTest> + +#include <QCalendar> +Q_DECLARE_METATYPE(QCalendar::System) + +class tst_QCalendar : public QObject +{ + Q_OBJECT +private: + void checkYear(const QCalendar &cal, int year, bool normal=false); + +private slots: + void basic_data(); + void basic(); + void nameCase(); + void specific_data(); + void specific(); + void daily_data() { basic_data(); } + void daily(); +}; + +// Support for basic(): +void tst_QCalendar::checkYear(const QCalendar &cal, int year, bool normal) +{ + const int moons = cal.monthsInYear(year); + // Months are numbered from 1 to moons: + QVERIFY(moons > 0); + QVERIFY(!cal.isDateValid(year, moons + 1, 1)); + QVERIFY(!cal.isDateValid(year, 0, 1)); + QVERIFY(moons <= cal.maximumMonthsInYear()); + + const int days = cal.daysInYear(year); + QVERIFY(days > 0); + + int sum = 0; + const int longest = cal.maximumDaysInMonth(); + for (int i = moons; i > 0; i--) { + const int last = cal.daysInMonth(i, year); + sum += last; + // Valid month has some days and no more than max: + QVERIFY(last > 0); + QVERIFY(last <= longest); + // Days are numbered from 1 to last: + QVERIFY(cal.isDateValid(year, i, 1)); + QVERIFY(cal.isDateValid(year, i, last)); + QVERIFY(!cal.isDateValid(year, i, 0)); + QVERIFY(!cal.isDateValid(year, i, last + 1)); + if (normal) // Unspecified year gets same daysInMonth(): + QCOMPARE(cal.daysInMonth(i), last); + } + // Months add up to the whole year: + QCOMPARE(sum, days); +} + +#define CHECKYEAR(cal, year) checkYear(cal, year); \ + if (QTest::currentTestFailed()) \ + return + +#define NORMALYEAR(cal, year) checkYear(cal, year, true); \ + if (QTest::currentTestFailed()) \ + return + +void tst_QCalendar::basic_data() +{ + QTest::addColumn<QCalendar::System>("system"); + + QMetaEnum e = QCalendar::staticMetaObject.enumerator(0); + Q_ASSERT(qstrcmp(e.name(), "System") == 0); + + for (int i = 0; i <= int(QCalendar::System::Last); ++i) { + // There may be gaps in the enum's numbering; and Last is a duplicate: + if (e.value(i) != -1 && qstrcmp(e.key(i), "Last")) + QTest::newRow(e.key(i)) << QCalendar::System(e.value(i)); + } +} + +void tst_QCalendar::basic() +{ + QFETCH(QCalendar::System, system); + QCalendar cal(system); + QVERIFY(cal.isValid()); + QCOMPARE(QCalendar(cal.name()).isGregorian(), cal.isGregorian()); + QCOMPARE(QCalendar(cal.name()).name(), cal.name()); + + if (cal.hasYearZero()) { + CHECKYEAR(cal, 0); + } else { + QCOMPARE(cal.monthsInYear(0), 0); + QCOMPARE(cal.daysInYear(0), 0); + QVERIFY(!cal.isDateValid(0, 1, 1)); + } + + if (cal.isProleptic()) { + CHECKYEAR(cal, -1); + } else { + QCOMPARE(cal.monthsInYear(-1), 0); + QCOMPARE(cal.daysInYear(-1), 0); + QVERIFY(!cal.isDateValid(-1, 1, 1)); + } + + // Look for a leap year in the last decade. + int year = QDate::currentDate().year(cal); + for (int i = 10; i > 0 && !cal.isLeapYear(year); --i) + --year; + if (cal.isLeapYear(year)) { + // ... and a non-leap year within a decade before it. + int leap = year--; + for (int i = 10; i > 0 && cal.isLeapYear(year); --i) + year--; + if (!cal.isLeapYear(year)) + QVERIFY(cal.daysInYear(year) < cal.daysInYear(leap)); + + CHECKYEAR(cal, leap); + } + // Either year is non-leap or we have a decade of leap years together; + // expect daysInMonth() to treat year the same as unspecified. + NORMALYEAR(cal, year); +} + +void tst_QCalendar::nameCase() +{ + QVERIFY(QCalendar::availableCalendars().contains(QStringLiteral("Gregorian"))); +} + +void tst_QCalendar::specific_data() +{ + QTest::addColumn<QCalendar::System>("system"); + // Date in that system: + QTest::addColumn<int>("sysyear"); + QTest::addColumn<int>("sysmonth"); + QTest::addColumn<int>("sysday"); + // Gregorian equivalent: + QTest::addColumn<int>("gregyear"); + QTest::addColumn<int>("gregmonth"); + QTest::addColumn<int>("gregday"); + +#define ADDROW(cal, year, month, day, gy, gm, gd) \ + QTest::newRow(#cal) << QCalendar::System::cal << year << month << day << gy << gm << gd + + ADDROW(Gregorian, 1970, 1, 1, 1970, 1, 1); + + // One known specific date, for each calendar +#ifndef QT_BOOTSTRAPPED + // Julian 1582-10-4 was followed by Gregorian 1582-10-15 + ADDROW(Julian, 1582, 10, 4, 1582, 10, 14); + // Milankovic matches Gregorian for a few centuries + ADDROW(Milankovic, 1923, 3, 20, 1923, 3, 20); +#endif + +#if QT_CONFIG(jalalicalendar) + // Jalali year 1355 started on Gregorian 1976-3-21: + ADDROW(Jalali, 1355, 1, 1, 1976, 3, 21); +#endif // jalali +#if QT_CONFIG(islamiccivilcalendar) + // TODO: confirm this is correct + ADDROW(IslamicCivil, 1, 1, 1, 622, 7, 19); +#endif + +#undef ADDROW +} + +void tst_QCalendar::specific() +{ + QFETCH(QCalendar::System, system); + QFETCH(int, sysyear); + QFETCH(int, sysmonth); + QFETCH(int, sysday); + QFETCH(int, gregyear); + QFETCH(int, gregmonth); + QFETCH(int, gregday); + + const QCalendar cal(system); + const QDate date(sysyear, sysmonth, sysday, cal), gregory(gregyear, gregmonth, gregday); + QCOMPARE(date, gregory); + QCOMPARE(gregory.year(cal), sysyear); + QCOMPARE(gregory.month(cal), sysmonth); + QCOMPARE(gregory.day(cal), sysday); + QCOMPARE(date.year(), gregyear); + QCOMPARE(date.month(), gregmonth); + QCOMPARE(date.day(), gregday); +} + +void tst_QCalendar::daily() +{ + QFETCH(QCalendar::System, system); + QCalendar calendar(system); + const quint64 startJDN = 0, endJDN = 2488070; + // Iterate from -4713-01-01 (Julian calendar) to 2100-01-01 + for (quint64 expect = startJDN; expect <= endJDN; ++expect) + { + QDate date = QDate::fromJulianDay(expect); + auto parts = calendar.partsFromDate(date); + if (!parts.isValid()) + continue; + + const int year = date.year(calendar); + QCOMPARE(year, parts.year); + const int month = date.month(calendar); + QCOMPARE(month, parts.month); + const int day = date.day(calendar); + QCOMPARE(day, parts.day); + const quint64 actual = QDate(year, month, day, calendar).toJulianDay(); + QCOMPARE(actual, expect); + } +} + +QTEST_APPLESS_MAIN(tst_QCalendar) +#include "tst_qcalendar.moc" |