1 /* 2 * Copyright (c) 2013, Opera Software ASA. All rights reserved. 3 * 4 * Redistribution and use in source and binary forms, with or without 5 * modification, are permitted provided that the following conditions 6 * are met: 7 * 1. Redistributions of source code must retain the above copyright 8 * notice, this list of conditions and the following disclaimer. 9 * 2. Redistributions in binary form must reproduce the above copyright 10 * notice, this list of conditions and the following disclaimer in the 11 * documentation and/or other materials provided with the distribution. 12 * 3. Neither the name of Opera Software ASA nor the names of its 13 * contributors may be used to endorse or promote products derived 14 * from this software without specific prior written permission. 15 * 16 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS 17 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT 18 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS 19 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE 20 * COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, 21 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 22 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 23 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 24 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 25 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 26 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 27 * OF THE POSSIBILITY OF SUCH DAMAGE. 28 */ 29 30 #include "config.h" 31 #include "core/html/track/vtt/VTTScanner.h" 32 33 #include "wtf/text/WTFString.h" 34 35 #include <gtest/gtest.h> 36 37 using blink::VTTScanner; 38 39 namespace { 40 41 TEST(VTTScanner, Constructor) 42 { 43 String data8("foo"); 44 EXPECT_TRUE(data8.is8Bit()); 45 VTTScanner scanner8(data8); 46 EXPECT_FALSE(scanner8.isAtEnd()); 47 48 String data16(data8); 49 data16.ensure16Bit(); 50 EXPECT_FALSE(data16.is8Bit()); 51 VTTScanner scanner16(data16); 52 EXPECT_FALSE(scanner16.isAtEnd()); 53 54 VTTScanner scannerEmpty(emptyString()); 55 EXPECT_TRUE(scannerEmpty.isAtEnd()); 56 } 57 58 void scanSequenceHelper1(const String& input) 59 { 60 VTTScanner scanner(input); 61 EXPECT_FALSE(scanner.isAtEnd()); 62 EXPECT_TRUE(scanner.match('f')); 63 EXPECT_FALSE(scanner.match('o')); 64 65 EXPECT_TRUE(scanner.scan('f')); 66 EXPECT_FALSE(scanner.match('f')); 67 EXPECT_TRUE(scanner.match('o')); 68 69 EXPECT_FALSE(scanner.scan('e')); 70 EXPECT_TRUE(scanner.scan('o')); 71 72 EXPECT_TRUE(scanner.scan('e')); 73 EXPECT_FALSE(scanner.match('e')); 74 75 EXPECT_TRUE(scanner.isAtEnd()); 76 } 77 78 // Run TESTFUNC with DATA in Latin and then UTF-16. (Requires DATA being Latin.) 79 #define TEST_WITH(TESTFUNC, DATA) do { \ 80 String data8(DATA); \ 81 EXPECT_TRUE(data8.is8Bit()); \ 82 TESTFUNC(data8); \ 83 \ 84 String data16(data8); \ 85 data16.ensure16Bit(); \ 86 EXPECT_FALSE(data16.is8Bit()); \ 87 TESTFUNC(data16); \ 88 } while (false) 89 90 91 // Exercises match(c) and scan(c). 92 TEST(VTTScanner, BasicOperations1) 93 { 94 TEST_WITH(scanSequenceHelper1, "foe"); 95 } 96 97 void scanSequenceHelper2(const String& input) 98 { 99 VTTScanner scanner(input); 100 EXPECT_FALSE(scanner.isAtEnd()); 101 EXPECT_FALSE(scanner.scan("fe")); 102 103 EXPECT_TRUE(scanner.scan("fo")); 104 EXPECT_FALSE(scanner.isAtEnd()); 105 106 EXPECT_FALSE(scanner.scan("ee")); 107 108 EXPECT_TRUE(scanner.scan('e')); 109 EXPECT_TRUE(scanner.isAtEnd()); 110 } 111 112 // Exercises scan(<literal>[, length]). 113 TEST(VTTScanner, BasicOperations2) 114 { 115 TEST_WITH(scanSequenceHelper2, "foe"); 116 } 117 118 bool lowerCaseAlpha(UChar c) 119 { 120 return c >= 'a' && c <= 'z'; 121 } 122 123 void scanWithPredicate(const String& input) 124 { 125 VTTScanner scanner(input); 126 EXPECT_FALSE(scanner.isAtEnd()); 127 // Collect "bad". 128 VTTScanner::Run lcRun = scanner.collectWhile<lowerCaseAlpha>(); 129 // collectWhile doesn't move the scan position. 130 EXPECT_TRUE(scanner.match('b')); 131 // Consume "bad". 132 scanner.skipWhile<lowerCaseAlpha>(); 133 EXPECT_TRUE(scanner.match('A')); 134 EXPECT_TRUE(scanner.isAt(lcRun.end())); 135 136 // Consume "A". 137 EXPECT_TRUE(scanner.scan('A')); 138 139 // Collect "bing". 140 lcRun = scanner.collectWhile<lowerCaseAlpha>(); 141 // collectWhile doesn't move the scan position. 142 EXPECT_FALSE(scanner.isAtEnd()); 143 // Consume "bing". 144 scanner.skipWhile<lowerCaseAlpha>(); 145 EXPECT_TRUE(scanner.isAt(lcRun.end())); 146 EXPECT_TRUE(scanner.isAtEnd()); 147 } 148 149 // Tests skipWhile() and collectWhile(). 150 TEST(VTTScanner, PredicateScanning) 151 { 152 TEST_WITH(scanWithPredicate, "badAbing"); 153 } 154 155 void scanWithInvPredicate(const String& input) 156 { 157 VTTScanner scanner(input); 158 EXPECT_FALSE(scanner.isAtEnd()); 159 // Collect "BAD". 160 VTTScanner::Run ucRun = scanner.collectUntil<lowerCaseAlpha>(); 161 // collectUntil doesn't move the scan position. 162 EXPECT_TRUE(scanner.match('B')); 163 // Consume "BAD". 164 scanner.skipUntil<lowerCaseAlpha>(); 165 EXPECT_TRUE(scanner.match('a')); 166 EXPECT_TRUE(scanner.isAt(ucRun.end())); 167 168 // Consume "a". 169 EXPECT_TRUE(scanner.scan('a')); 170 171 // Collect "BING". 172 ucRun = scanner.collectUntil<lowerCaseAlpha>(); 173 // collectUntil doesn't move the scan position. 174 EXPECT_FALSE(scanner.isAtEnd()); 175 // Consume "BING". 176 scanner.skipUntil<lowerCaseAlpha>(); 177 EXPECT_TRUE(scanner.isAt(ucRun.end())); 178 EXPECT_TRUE(scanner.isAtEnd()); 179 } 180 181 // Tests skipUntil() and collectUntil(). 182 TEST(VTTScanner, InversePredicateScanning) 183 { 184 TEST_WITH(scanWithInvPredicate, "BADaBING"); 185 } 186 187 void scanRuns(const String& input) 188 { 189 String fooString("foo"); 190 String barString("bar"); 191 VTTScanner scanner(input); 192 EXPECT_FALSE(scanner.isAtEnd()); 193 VTTScanner::Run word = scanner.collectWhile<lowerCaseAlpha>(); 194 EXPECT_FALSE(scanner.scanRun(word, barString)); 195 EXPECT_TRUE(scanner.scanRun(word, fooString)); 196 197 EXPECT_TRUE(scanner.match(':')); 198 EXPECT_TRUE(scanner.scan(':')); 199 200 // Skip 'baz'. 201 scanner.skipRun(scanner.collectWhile<lowerCaseAlpha>()); 202 203 EXPECT_TRUE(scanner.match(':')); 204 EXPECT_TRUE(scanner.scan(':')); 205 206 word = scanner.collectWhile<lowerCaseAlpha>(); 207 EXPECT_FALSE(scanner.scanRun(word, fooString)); 208 EXPECT_TRUE(scanner.scanRun(word, barString)); 209 EXPECT_TRUE(scanner.isAtEnd()); 210 } 211 212 // Tests scanRun/skipRun. 213 TEST(VTTScanner, RunScanning) 214 { 215 TEST_WITH(scanRuns, "foo:baz:bar"); 216 } 217 218 void scanRunsToStrings(const String& input) 219 { 220 VTTScanner scanner(input); 221 EXPECT_FALSE(scanner.isAtEnd()); 222 VTTScanner::Run word = scanner.collectWhile<lowerCaseAlpha>(); 223 String fooString = scanner.extractString(word); 224 EXPECT_EQ(fooString, "foo"); 225 EXPECT_TRUE(scanner.isAt(word.end())); 226 227 EXPECT_TRUE(scanner.match(':')); 228 EXPECT_TRUE(scanner.scan(':')); 229 230 word = scanner.collectWhile<lowerCaseAlpha>(); 231 String barString = scanner.extractString(word); 232 EXPECT_EQ(barString, "bar"); 233 EXPECT_TRUE(scanner.isAt(word.end())); 234 EXPECT_TRUE(scanner.isAtEnd()); 235 } 236 237 // Tests extractString. 238 TEST(VTTScanner, ExtractString) 239 { 240 TEST_WITH(scanRunsToStrings, "foo:bar"); 241 } 242 243 void tailStringExtract(const String& input) 244 { 245 VTTScanner scanner(input); 246 EXPECT_TRUE(scanner.scan("foo")); 247 EXPECT_TRUE(scanner.scan(':')); 248 String barSuffix = scanner.restOfInputAsString(); 249 EXPECT_EQ(barSuffix, "bar"); 250 251 EXPECT_TRUE(scanner.isAtEnd()); 252 } 253 254 // Tests restOfInputAsString(). 255 TEST(VTTScanner, ExtractRestAsString) 256 { 257 TEST_WITH(tailStringExtract, "foo:bar"); 258 } 259 260 void scanDigits1(const String& input) 261 { 262 VTTScanner scanner(input); 263 EXPECT_TRUE(scanner.scan("foo")); 264 int number; 265 EXPECT_EQ(scanner.scanDigits(number), 0u); 266 EXPECT_EQ(number, 0); 267 EXPECT_TRUE(scanner.scan(' ')); 268 EXPECT_EQ(scanner.scanDigits(number), 3u); 269 EXPECT_TRUE(scanner.match(' ')); 270 EXPECT_EQ(number, 123); 271 272 EXPECT_TRUE(scanner.scan(' ')); 273 EXPECT_TRUE(scanner.scan("bar")); 274 EXPECT_TRUE(scanner.scan(' ')); 275 276 EXPECT_EQ(scanner.scanDigits(number), 5u); 277 EXPECT_EQ(number, 45678); 278 279 EXPECT_TRUE(scanner.isAtEnd()); 280 } 281 282 void scanDigits2(const String& input) 283 { 284 VTTScanner scanner(input); 285 int number; 286 EXPECT_EQ(scanner.scanDigits(number), 0u); 287 EXPECT_EQ(number, 0); 288 EXPECT_TRUE(scanner.scan('-')); 289 EXPECT_EQ(scanner.scanDigits(number), 3u); 290 EXPECT_EQ(number, 654); 291 292 EXPECT_TRUE(scanner.scan(' ')); 293 294 EXPECT_EQ(scanner.scanDigits(number), 19u); 295 EXPECT_EQ(number, std::numeric_limits<int>::max()); 296 297 EXPECT_TRUE(scanner.isAtEnd()); 298 } 299 300 // Tests scanDigits(). 301 TEST(VTTScanner, ScanDigits) 302 { 303 TEST_WITH(scanDigits1, "foo 123 bar 45678"); 304 TEST_WITH(scanDigits2, "-654 1000000000000000000"); 305 } 306 307 void scanFloatValue(const String& input) 308 { 309 VTTScanner scanner(input); 310 float value; 311 // "1." 312 EXPECT_TRUE(scanner.scanFloat(value)); 313 EXPECT_EQ(value, 1.0f); 314 EXPECT_TRUE(scanner.scan(' ')); 315 316 // "1.0" 317 EXPECT_TRUE(scanner.scanFloat(value)); 318 EXPECT_EQ(value, 1.0f); 319 EXPECT_TRUE(scanner.scan(' ')); 320 321 // ".0" 322 EXPECT_TRUE(scanner.scanFloat(value)); 323 EXPECT_EQ(value, 0.0f); 324 EXPECT_TRUE(scanner.scan(' ')); 325 326 // "." (invalid) 327 EXPECT_FALSE(scanner.scanFloat(value)); 328 EXPECT_TRUE(scanner.match('.')); 329 EXPECT_TRUE(scanner.scan('.')); 330 EXPECT_TRUE(scanner.scan(' ')); 331 332 // "1.0000" 333 EXPECT_TRUE(scanner.scanFloat(value)); 334 EXPECT_EQ(value, 1.0f); 335 EXPECT_TRUE(scanner.scan(' ')); 336 337 // "01.000" 338 EXPECT_TRUE(scanner.scanFloat(value)); 339 EXPECT_EQ(value, 1.0f); 340 341 EXPECT_TRUE(scanner.isAtEnd()); 342 } 343 344 // Tests scanFloat(). 345 TEST(VTTScanner, ScanFloat) 346 { 347 TEST_WITH(scanFloatValue, "1. 1.0 .0 . 1.0000 01.000"); 348 } 349 350 #undef TEST_WITH 351 352 } // namespace 353