完成 0.2.0 预发布收口与中文安装器
This commit is contained in:
@@ -1,8 +1,34 @@
|
||||
#include "TestHarness.h"
|
||||
|
||||
#include "src/weather/WeatherParser.h"
|
||||
#include "src/weather/WeatherLocationResolver.h"
|
||||
#include "src/weather/WeatherSummaryFormatter.h"
|
||||
|
||||
namespace
|
||||
{
|
||||
WeatherLocationCandidate candidate(
|
||||
const QString &city,
|
||||
const QString &admin,
|
||||
const QString &country,
|
||||
const QString &countryCode,
|
||||
const QString &featureCode,
|
||||
qint64 population,
|
||||
double latitude,
|
||||
double longitude)
|
||||
{
|
||||
WeatherLocationCandidate value;
|
||||
value.cityName = city;
|
||||
value.adminName = admin;
|
||||
value.countryName = country;
|
||||
value.countryCode = countryCode;
|
||||
value.featureCode = featureCode;
|
||||
value.population = population;
|
||||
value.latitude = latitude;
|
||||
value.longitude = longitude;
|
||||
return value;
|
||||
}
|
||||
}
|
||||
|
||||
QA_TEST(WeatherParser, ExtractsExplicitCitiesAndDates)
|
||||
{
|
||||
const WeatherParser parser;
|
||||
@@ -38,6 +64,120 @@ QA_TEST(WeatherParser, RejectsUnsupportedQueries)
|
||||
QA_EXPECT(!parser.parse(QStringLiteral("明天穿什么")).unsupportedReason.isEmpty());
|
||||
}
|
||||
|
||||
QA_TEST(WeatherLocationResolver, ResolvesChineseInternationalCities)
|
||||
{
|
||||
const WeatherLocationSearch newYork = WeatherLocationResolver::resolveSearch(QStringLiteral("纽约"));
|
||||
const WeatherLocationSearch tokyo = WeatherLocationResolver::resolveSearch(QStringLiteral("东京"));
|
||||
const WeatherLocationSearch japanTokyo = WeatherLocationResolver::resolveSearch(QStringLiteral("日本东京"));
|
||||
const WeatherLocationSearch qualifiedTokyo = WeatherLocationResolver::resolveSearch(QStringLiteral("东京,日本"));
|
||||
|
||||
QA_EXPECT_EQ(newYork.queryName, QStringLiteral("New York"));
|
||||
QA_EXPECT_EQ(newYork.countryCode, QStringLiteral("US"));
|
||||
QA_EXPECT_EQ(tokyo.queryName, QStringLiteral("Tokyo"));
|
||||
QA_EXPECT_EQ(tokyo.countryCode, QStringLiteral("JP"));
|
||||
QA_EXPECT_EQ(japanTokyo.queryName, QStringLiteral("Tokyo"));
|
||||
QA_EXPECT_EQ(japanTokyo.countryCode, QStringLiteral("JP"));
|
||||
QA_EXPECT_EQ(qualifiedTokyo.queryName, QStringLiteral("Tokyo"));
|
||||
QA_EXPECT_EQ(qualifiedTokyo.countryCode, QStringLiteral("JP"));
|
||||
}
|
||||
|
||||
QA_TEST(WeatherLocationResolver, PreservesDomesticCityAndCountryQualifier)
|
||||
{
|
||||
const WeatherLocationSearch xian = WeatherLocationResolver::resolveSearch(QStringLiteral("西安市"));
|
||||
const WeatherLocationSearch chinaXian = WeatherLocationResolver::resolveSearch(QStringLiteral("中国西安"));
|
||||
|
||||
QA_EXPECT_EQ(xian.queryName, QStringLiteral("西安"));
|
||||
QA_EXPECT(xian.countryCode.isEmpty());
|
||||
QA_EXPECT_EQ(chinaXian.queryName, QStringLiteral("西安"));
|
||||
QA_EXPECT_EQ(chinaXian.countryCode, QStringLiteral("CN"));
|
||||
}
|
||||
|
||||
QA_TEST(WeatherLocationResolver, SuppressesLowValueAlternatives)
|
||||
{
|
||||
const QVector<WeatherLocationCandidate> candidates = {
|
||||
candidate(QStringLiteral("西安"), QStringLiteral("陕西"), QStringLiteral("中国"), QStringLiteral("CN"), QStringLiteral("PPLA"), 6500000, 34.26, 108.93),
|
||||
candidate(QStringLiteral("西安"), QStringLiteral("湖南"), QStringLiteral("中国"), QStringLiteral("CN"), QStringLiteral("PPL"), 1200, 27.10, 111.20),
|
||||
candidate(QStringLiteral("西安"), QStringLiteral("广东"), QStringLiteral("中国"), QStringLiteral("CN"), QStringLiteral("PPL"), -1, 23.10, 113.20),
|
||||
};
|
||||
|
||||
const QVector<WeatherLocationCandidate> selected = WeatherLocationResolver::selectRelevantCandidates(
|
||||
candidates,
|
||||
WeatherLocationResolver::resolveSearch(QStringLiteral("西安")));
|
||||
QA_EXPECT_EQ(selected.size(), 1);
|
||||
QA_EXPECT(!WeatherLocationResolver::hasAmbiguity(selected));
|
||||
}
|
||||
|
||||
QA_TEST(WeatherLocationResolver, KeepsPlausibleAmbiguity)
|
||||
{
|
||||
const QVector<WeatherLocationCandidate> candidates = {
|
||||
candidate(QStringLiteral("Springfield"), QStringLiteral("Missouri"), QStringLiteral("United States"), QStringLiteral("US"), QStringLiteral("PPLA2"), 170000, 37.21, -93.29),
|
||||
candidate(QStringLiteral("Springfield"), QStringLiteral("Illinois"), QStringLiteral("United States"), QStringLiteral("US"), QStringLiteral("PPLA"), 114000, 39.80, -89.64),
|
||||
candidate(QStringLiteral("Springfield"), QStringLiteral("Georgia"), QStringLiteral("United States"), QStringLiteral("US"), QStringLiteral("PPL"), 2700, 32.37, -81.31),
|
||||
};
|
||||
|
||||
const QVector<WeatherLocationCandidate> selected = WeatherLocationResolver::selectRelevantCandidates(
|
||||
candidates,
|
||||
WeatherLocationResolver::resolveSearch(QStringLiteral("Springfield")));
|
||||
QA_EXPECT_EQ(selected.size(), 2);
|
||||
QA_EXPECT(WeatherLocationResolver::hasAmbiguity(selected));
|
||||
}
|
||||
|
||||
QA_TEST(WeatherLocationResolver, AppliesExplicitCountryFilter)
|
||||
{
|
||||
const QVector<WeatherLocationCandidate> candidates = {
|
||||
candidate(QStringLiteral("Tokyo"), QStringLiteral("Tokyo"), QStringLiteral("Japan"), QStringLiteral("JP"), QStringLiteral("PPLC"), 8300000, 35.68, 139.69),
|
||||
candidate(QStringLiteral("Tokyo"), QStringLiteral("Texas"), QStringLiteral("United States"), QStringLiteral("US"), QStringLiteral("PPL"), 1000, 33.90, -102.50),
|
||||
};
|
||||
|
||||
const QVector<WeatherLocationCandidate> selected = WeatherLocationResolver::selectRelevantCandidates(
|
||||
candidates,
|
||||
WeatherLocationResolver::resolveSearch(QStringLiteral("日本东京")));
|
||||
QA_EXPECT_EQ(selected.size(), 1);
|
||||
QA_EXPECT_EQ(selected.first().countryCode, QStringLiteral("JP"));
|
||||
}
|
||||
|
||||
QA_TEST(WeatherLocationResolver, ParsesBothIpLocationSchemas)
|
||||
{
|
||||
const QByteArray ipApiPayload = QByteArrayLiteral(
|
||||
R"({"city":"Xi'an","region":"Shaanxi","country_name":"China","latitude":34.26,"longitude":108.94,"timezone":"Asia/Shanghai"})");
|
||||
const QByteArray ipWhoIsPayload = QByteArrayLiteral(
|
||||
R"({"success":true,"city":"Tokyo","region":"Tokyo","country":"Japan","latitude":35.68,"longitude":139.69,"timezone":{"id":"Asia/Tokyo"}})");
|
||||
|
||||
WeatherLocation ipApiLocation;
|
||||
WeatherLocation ipWhoIsLocation;
|
||||
QA_EXPECT(WeatherLocationResolver::parseIpLocationResponse(
|
||||
ipApiPayload,
|
||||
WeatherIpLocationProvider::IpApiCo,
|
||||
&ipApiLocation));
|
||||
QA_EXPECT(WeatherLocationResolver::parseIpLocationResponse(
|
||||
ipWhoIsPayload,
|
||||
WeatherIpLocationProvider::IpWhoIs,
|
||||
&ipWhoIsLocation));
|
||||
QA_EXPECT_EQ(ipApiLocation.cityName, QStringLiteral("Xi'an"));
|
||||
QA_EXPECT_EQ(ipApiLocation.countryName, QStringLiteral("China"));
|
||||
QA_EXPECT_EQ(ipApiLocation.timezone, QStringLiteral("Asia/Shanghai"));
|
||||
QA_EXPECT_EQ(ipWhoIsLocation.cityName, QStringLiteral("Tokyo"));
|
||||
QA_EXPECT_EQ(ipWhoIsLocation.countryName, QStringLiteral("Japan"));
|
||||
QA_EXPECT_EQ(ipWhoIsLocation.timezone, QStringLiteral("Asia/Tokyo"));
|
||||
}
|
||||
|
||||
QA_TEST(WeatherLocationResolver, RejectsBrokenIpLocationResponses)
|
||||
{
|
||||
WeatherLocation location;
|
||||
QA_EXPECT(!WeatherLocationResolver::parseIpLocationResponse(
|
||||
QByteArrayLiteral("{broken"),
|
||||
WeatherIpLocationProvider::IpApiCo,
|
||||
&location));
|
||||
QA_EXPECT(!WeatherLocationResolver::parseIpLocationResponse(
|
||||
QByteArrayLiteral(R"({"success":false,"message":"rate limited"})"),
|
||||
WeatherIpLocationProvider::IpWhoIs,
|
||||
&location));
|
||||
QA_EXPECT(!WeatherLocationResolver::parseIpLocationResponse(
|
||||
QByteArrayLiteral(R"({"city":"Tokyo","latitude":35.68})"),
|
||||
WeatherIpLocationProvider::IpWhoIs,
|
||||
&location));
|
||||
}
|
||||
|
||||
QA_TEST(WeatherFormatter, MapsWeatherCodesAndWindDirections)
|
||||
{
|
||||
QA_EXPECT_EQ(WeatherSummaryFormatter::weatherCodeText(0), QStringLiteral("晴"));
|
||||
|
||||
Reference in New Issue
Block a user