blob: d5bcfb8f52fd1433232cecca9dd60f69ca0b8f47 [file] [log] [blame]
/*
* Copyright (c) 2013, Opera Software ASA. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. 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.
* 3. Neither the name of Opera Software ASA 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "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 THE
* COPYRIGHT HOLDER OR CONTRIBUTORS 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 "config.h"
#include "core/html/track/vtt/VTTScanner.h"
#include "wtf/text/WTFString.h"
#include <gtest/gtest.h>
using WebCore::VTTScanner;
namespace {
TEST(VTTScanner, Constructor)
{
String data8("foo");
EXPECT_TRUE(data8.is8Bit());
VTTScanner scanner8(data8);
EXPECT_FALSE(scanner8.isAtEnd());
String data16(data8);
data16.ensure16Bit();
EXPECT_FALSE(data16.is8Bit());
VTTScanner scanner16(data16);
EXPECT_FALSE(scanner16.isAtEnd());
VTTScanner scannerEmpty(emptyString());
EXPECT_TRUE(scannerEmpty.isAtEnd());
}
void scanSequenceHelper1(const String& input)
{
VTTScanner scanner(input);
EXPECT_FALSE(scanner.isAtEnd());
EXPECT_TRUE(scanner.match('f'));
EXPECT_FALSE(scanner.match('o'));
EXPECT_TRUE(scanner.scan('f'));
EXPECT_FALSE(scanner.match('f'));
EXPECT_TRUE(scanner.match('o'));
EXPECT_FALSE(scanner.scan('e'));
EXPECT_TRUE(scanner.scan('o'));
EXPECT_TRUE(scanner.scan('e'));
EXPECT_FALSE(scanner.match('e'));
EXPECT_TRUE(scanner.isAtEnd());
}
// Run TESTFUNC with DATA in Latin and then UTF-16. (Requires DATA being Latin.)
#define TEST_WITH(TESTFUNC, DATA) do { \
String data8(DATA); \
EXPECT_TRUE(data8.is8Bit()); \
TESTFUNC(data8); \
\
String data16(data8); \
data16.ensure16Bit(); \
EXPECT_FALSE(data16.is8Bit()); \
TESTFUNC(data16); \
} while (false)
// Exercises match(c) and scan(c).
TEST(VTTScanner, BasicOperations1)
{
TEST_WITH(scanSequenceHelper1, "foe");
}
void scanSequenceHelper2(const String& input)
{
VTTScanner scanner(input);
EXPECT_FALSE(scanner.isAtEnd());
EXPECT_FALSE(scanner.scan("fe"));
EXPECT_TRUE(scanner.scan("fo"));
EXPECT_FALSE(scanner.isAtEnd());
EXPECT_FALSE(scanner.scan("ee"));
EXPECT_TRUE(scanner.scan('e'));
EXPECT_TRUE(scanner.isAtEnd());
}
// Exercises scan(<literal>[, length]).
TEST(VTTScanner, BasicOperations2)
{
TEST_WITH(scanSequenceHelper2, "foe");
}
bool lowerCaseAlpha(UChar c)
{
return c >= 'a' && c <= 'z';
}
void scanWithPredicate(const String& input)
{
VTTScanner scanner(input);
EXPECT_FALSE(scanner.isAtEnd());
// Collect "bad".
VTTScanner::Run lcRun = scanner.collectWhile<lowerCaseAlpha>();
// collectWhile doesn't move the scan position.
EXPECT_TRUE(scanner.match('b'));
// Consume "bad".
scanner.skipWhile<lowerCaseAlpha>();
EXPECT_TRUE(scanner.match('A'));
EXPECT_TRUE(scanner.isAt(lcRun.end()));
// Consume "A".
EXPECT_TRUE(scanner.scan('A'));
// Collect "bing".
lcRun = scanner.collectWhile<lowerCaseAlpha>();
// collectWhile doesn't move the scan position.
EXPECT_FALSE(scanner.isAtEnd());
// Consume "bing".
scanner.skipWhile<lowerCaseAlpha>();
EXPECT_TRUE(scanner.isAt(lcRun.end()));
EXPECT_TRUE(scanner.isAtEnd());
}
// Tests skipWhile() and collectWhile().
TEST(VTTScanner, PredicateScanning)
{
TEST_WITH(scanWithPredicate, "badAbing");
}
void scanWithInvPredicate(const String& input)
{
VTTScanner scanner(input);
EXPECT_FALSE(scanner.isAtEnd());
// Collect "BAD".
VTTScanner::Run ucRun = scanner.collectUntil<lowerCaseAlpha>();
// collectUntil doesn't move the scan position.
EXPECT_TRUE(scanner.match('B'));
// Consume "BAD".
scanner.skipUntil<lowerCaseAlpha>();
EXPECT_TRUE(scanner.match('a'));
EXPECT_TRUE(scanner.isAt(ucRun.end()));
// Consume "a".
EXPECT_TRUE(scanner.scan('a'));
// Collect "BING".
ucRun = scanner.collectUntil<lowerCaseAlpha>();
// collectUntil doesn't move the scan position.
EXPECT_FALSE(scanner.isAtEnd());
// Consume "BING".
scanner.skipUntil<lowerCaseAlpha>();
EXPECT_TRUE(scanner.isAt(ucRun.end()));
EXPECT_TRUE(scanner.isAtEnd());
}
// Tests skipUntil() and collectUntil().
TEST(VTTScanner, InversePredicateScanning)
{
TEST_WITH(scanWithInvPredicate, "BADaBING");
}
void scanRuns(const String& input)
{
String fooString("foo");
String barString("bar");
VTTScanner scanner(input);
EXPECT_FALSE(scanner.isAtEnd());
VTTScanner::Run word = scanner.collectWhile<lowerCaseAlpha>();
EXPECT_FALSE(scanner.scanRun(word, barString));
EXPECT_TRUE(scanner.scanRun(word, fooString));
EXPECT_TRUE(scanner.match(':'));
EXPECT_TRUE(scanner.scan(':'));
// Skip 'baz'.
scanner.skipRun(scanner.collectWhile<lowerCaseAlpha>());
EXPECT_TRUE(scanner.match(':'));
EXPECT_TRUE(scanner.scan(':'));
word = scanner.collectWhile<lowerCaseAlpha>();
EXPECT_FALSE(scanner.scanRun(word, fooString));
EXPECT_TRUE(scanner.scanRun(word, barString));
EXPECT_TRUE(scanner.isAtEnd());
}
// Tests scanRun/skipRun.
TEST(VTTScanner, RunScanning)
{
TEST_WITH(scanRuns, "foo:baz:bar");
}
void scanRunsToStrings(const String& input)
{
VTTScanner scanner(input);
EXPECT_FALSE(scanner.isAtEnd());
VTTScanner::Run word = scanner.collectWhile<lowerCaseAlpha>();
String fooString = scanner.extractString(word);
EXPECT_EQ(fooString, "foo");
EXPECT_TRUE(scanner.isAt(word.end()));
EXPECT_TRUE(scanner.match(':'));
EXPECT_TRUE(scanner.scan(':'));
word = scanner.collectWhile<lowerCaseAlpha>();
String barString = scanner.extractString(word);
EXPECT_EQ(barString, "bar");
EXPECT_TRUE(scanner.isAt(word.end()));
EXPECT_TRUE(scanner.isAtEnd());
}
// Tests extractString.
TEST(VTTScanner, ExtractString)
{
TEST_WITH(scanRunsToStrings, "foo:bar");
}
void tailStringExtract(const String& input)
{
VTTScanner scanner(input);
EXPECT_TRUE(scanner.scan("foo"));
EXPECT_TRUE(scanner.scan(':'));
String barSuffix = scanner.restOfInputAsString();
EXPECT_EQ(barSuffix, "bar");
EXPECT_TRUE(scanner.isAtEnd());
}
// Tests restOfInputAsString().
TEST(VTTScanner, ExtractRestAsString)
{
TEST_WITH(tailStringExtract, "foo:bar");
}
void scanDigits1(const String& input)
{
VTTScanner scanner(input);
EXPECT_TRUE(scanner.scan("foo"));
int number;
EXPECT_EQ(scanner.scanDigits(number), 0u);
EXPECT_EQ(number, 0);
EXPECT_TRUE(scanner.scan(' '));
EXPECT_EQ(scanner.scanDigits(number), 3u);
EXPECT_TRUE(scanner.match(' '));
EXPECT_EQ(number, 123);
EXPECT_TRUE(scanner.scan(' '));
EXPECT_TRUE(scanner.scan("bar"));
EXPECT_TRUE(scanner.scan(' '));
EXPECT_EQ(scanner.scanDigits(number), 5u);
EXPECT_EQ(number, 45678);
EXPECT_TRUE(scanner.isAtEnd());
}
void scanDigits2(const String& input)
{
VTTScanner scanner(input);
int number;
EXPECT_EQ(scanner.scanDigits(number), 0u);
EXPECT_EQ(number, 0);
EXPECT_TRUE(scanner.scan('-'));
EXPECT_EQ(scanner.scanDigits(number), 3u);
EXPECT_EQ(number, 654);
EXPECT_TRUE(scanner.scan(' '));
EXPECT_EQ(scanner.scanDigits(number), 19u);
EXPECT_EQ(number, std::numeric_limits<int>::max());
EXPECT_TRUE(scanner.isAtEnd());
}
// Tests scanDigits().
TEST(VTTScanner, ScanDigits)
{
TEST_WITH(scanDigits1, "foo 123 bar 45678");
TEST_WITH(scanDigits2, "-654 1000000000000000000");
}
void scanFloatValue(const String& input)
{
VTTScanner scanner(input);
float value;
// "1."
EXPECT_TRUE(scanner.scanFloat(value));
EXPECT_EQ(value, 1.0f);
EXPECT_TRUE(scanner.scan(' '));
// "1.0"
EXPECT_TRUE(scanner.scanFloat(value));
EXPECT_EQ(value, 1.0f);
EXPECT_TRUE(scanner.scan(' '));
// ".0"
EXPECT_TRUE(scanner.scanFloat(value));
EXPECT_EQ(value, 0.0f);
EXPECT_TRUE(scanner.scan(' '));
// "." (invalid)
EXPECT_FALSE(scanner.scanFloat(value));
EXPECT_TRUE(scanner.match('.'));
EXPECT_TRUE(scanner.scan('.'));
EXPECT_TRUE(scanner.scan(' '));
// "1.0000"
EXPECT_TRUE(scanner.scanFloat(value));
EXPECT_EQ(value, 1.0f);
EXPECT_TRUE(scanner.scan(' '));
// "01.000"
EXPECT_TRUE(scanner.scanFloat(value));
EXPECT_EQ(value, 1.0f);
EXPECT_TRUE(scanner.isAtEnd());
}
// Tests scanFloat().
TEST(VTTScanner, ScanFloat)
{
TEST_WITH(scanFloatValue, "1. 1.0 .0 . 1.0000 01.000");
}
#undef TEST_WITH
} // namespace