Permalink
Switch branches/tags
Nothing to show
Find file
Fetching contributors…
Cannot retrieve contributors at this time
204 lines (162 sloc) 7.52 KB
/*
Copyright (C) Research In Motion Limited 2009. All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
* Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
* Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
* Neither the name of Research In Motion Limited nor the
names of its contributors may be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY Research In Motion Limited ''AS IS'' AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL Research In Motion Limited BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
#include <qtest.h>
#include <qdiriterator.h>
#include <qurl.h>
/*!
Returns a valid URL from a user supplied string if one can be deducted.
In the case that is not possible, an invalid QUrl() is returned.
\since 4.6
Most applications that can browse the web, allow the user to input a URL
in the form of a plain string. This string can be manually typed into
a location bar, obtained from the clipboard, or passed in via command
line arguments.
When the string is not already a valid URL, a best guess is performed,
making various web related assumptions.
In the case the string corresponds to a valid file path on the system,
a file:// URL is constructed, using QUrl::fromLocalFile().
If that is not the case, an attempt is made to turn the string into a
http:// or ftp:// URL. The latter in the case the string starts with
'ftp'. The result is then passed through QUrl's tolerant parser, and
in the case or success, a valid QUrl is returned, orelse a QUrl().
Examples
- webkit.org becomes http://webkit.org
- ftp.webkit.org becomes ftp://ftp.webkit.org
- localhost becomes http://localhost
- /home/user/test.html becomes file:///home/user/test.html (if exists)
Tips when dealing with URLs and strings
- When creating a QString from a QByteArray or a char*, always use
QString::fromUtf8().
- Do not use QUrl(string), nor QUrl::toString() anywhere where the URL might
be used, such as in the location bar, as those functions loose data.
Instead use QUrl::fromEncoded() and QUrl::toEncoded(), respectively.
*/
static QUrl guessUrlFromString(const QString &string)
{
QString trimmedString = string.trimmed();
// Check the most common case of a valid url with scheme and host first
QUrl url = QUrl::fromEncoded(trimmedString.toUtf8(), QUrl::TolerantMode);
if (url.isValid() && !url.scheme().isEmpty() && !url.host().isEmpty())
return url;
// Absolute files that exists
if (QDir::isAbsolutePath(trimmedString) && QFile::exists(trimmedString))
return QUrl::fromLocalFile(trimmedString);
// If the string is missing the scheme or the scheme is not valid prepend a scheme
QString scheme = url.scheme();
if (scheme.isEmpty() || scheme.contains(QLatin1Char('.')) || scheme == QLatin1String("localhost")) {
// Do not do anything for strings such as "foo", only "foo.com"
int dotIndex = trimmedString.indexOf(QLatin1Char('.'));
if (dotIndex != -1 || trimmedString.startsWith(QLatin1String("localhost"))) {
const QString hostscheme = trimmedString.left(dotIndex).toLower();
QByteArray scheme = (hostscheme == QLatin1String("ftp")) ? "ftp" : "http";
trimmedString = QLatin1String(scheme) + QLatin1String("://") + trimmedString;
}
url = QUrl::fromEncoded(trimmedString.toUtf8(), QUrl::TolerantMode);
}
if (url.isValid())
return url;
return QUrl();
}
class tst_Guess : public QObject
{
Q_OBJECT
public slots:
void initTestCase();
void cleanupTestCase();
void init();
void cleanup();
private slots:
void guessUrlFromString_data();
void guessUrlFromString();
};
// This will be called before the first test function is executed.
// It is only called once.
void tst_Guess::initTestCase()
{
}
// This will be called after the last test function is executed.
// It is only called once.
void tst_Guess::cleanupTestCase()
{
}
// This will be called before each test function is executed.
void tst_Guess::init()
{
}
// This will be called after every test function.
void tst_Guess::cleanup()
{
}
void tst_Guess::guessUrlFromString_data()
{
QTest::addColumn<QString>("string");
QTest::addColumn<QUrl>("guessUrlFromString");
// Null
QTest::newRow("null") << QString() << QUrl();
// File
QDirIterator it(QDir::homePath());
QString fileString;
int c = 0;
while (it.hasNext()) {
it.next();
QTest::newRow(QString("file-%1").arg(c++).toLatin1()) << it.filePath() << QUrl::fromLocalFile(it.filePath());
}
// basic latin1
QTest::newRow("unicode-0") << QString::fromUtf8("å.com/") << QUrl::fromEncoded(QString::fromUtf8("http://å.com/").toUtf8(), QUrl::TolerantMode);
// unicode
QTest::newRow("unicode-1") << QString::fromUtf8("λ.com/") << QUrl::fromEncoded(QString::fromUtf8("http://λ.com/").toUtf8(), QUrl::TolerantMode);
// no scheme
QTest::newRow("add scheme-0") << "webkit.org" << QUrl("http://webkit.org");
QTest::newRow("add scheme-1") << "www.webkit.org" << QUrl("http://www.webkit.org");
QTest::newRow("add scheme-2") << "ftp.webkit.org" << QUrl("ftp://ftp.webkit.org");
QTest::newRow("add scheme-3") << "webkit" << QUrl("webkit");
// QUrl's tolerant parser should already handle this
QTest::newRow("not-encoded-0") << "http://webkit.org/test page.html" << QUrl("http://webkit.org/test%20page.html");
// Make sure the :80, i.e. port doesn't screw anything up
QUrl portUrl("http://webkit.org");
portUrl.setPort(80);
QTest::newRow("port-0") << "webkit.org:80" << portUrl;
QTest::newRow("port-1") << "http://webkit.org:80" << portUrl;
// mailto doesn't have a ://, but is valid
QUrl mailto("ben@meyerhome.net");
mailto.setScheme("mailto");
QTest::newRow("mailto") << "mailto:ben@meyerhome.net" << mailto;
// misc
QTest::newRow("localhost-0") << "localhost" << QUrl("http://localhost");
QTest::newRow("localhost-1") << "localhost:80" << QUrl("http://localhost:80");
QTest::newRow("spaces-0") << " http://webkit.org/test page.html " << QUrl("http://webkit.org/test%20page.html");
// FYI: The scheme in the resulting url user
QUrl authUrl("user:pass@domain.com");
QTest::newRow("misc-1") << "user:pass@domain.com" << authUrl;
}
// public static QUrl guessUrlFromString(QString const& string)
void tst_Guess::guessUrlFromString()
{
QFETCH(QString, string);
QFETCH(QUrl, guessUrlFromString);
QUrl url = ::guessUrlFromString(string);
QCOMPARE(url, guessUrlFromString);
}
QTEST_MAIN(tst_Guess)
#include "tst_guess.moc"