| /* |
| * Copyright (C) 2016 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| package com.google.android.exoplayer2.text.webvtt; |
| |
| import static com.google.android.exoplayer2.text.webvtt.CssParser.parseNextToken; |
| import static com.google.common.truth.Truth.assertThat; |
| |
| import androidx.test.ext.junit.runners.AndroidJUnit4; |
| import com.google.android.exoplayer2.util.ParsableByteArray; |
| import com.google.android.exoplayer2.util.Util; |
| import java.util.List; |
| import org.junit.Before; |
| import org.junit.Test; |
| import org.junit.runner.RunWith; |
| |
| /** Unit test for {@link CssParser}. */ |
| @RunWith(AndroidJUnit4.class) |
| public final class CssParserTest { |
| |
| private CssParser parser; |
| |
| @Before |
| public void setUp() { |
| parser = new CssParser(); |
| } |
| |
| @Test |
| public void skipWhitespacesAndComments() { |
| // Skip only whitespaces |
| String skipOnlyWhitespaces = " \t\r\n\f End of skip\n /* */"; |
| assertSkipsToEndOfSkip("End of skip", skipOnlyWhitespaces); |
| |
| // Skip only comments. |
| String skipOnlyComments = "/*A comment***//*/It even has spaces in it*/End of skip"; |
| assertSkipsToEndOfSkip("End of skip", skipOnlyComments); |
| |
| // Skip interleaved. |
| String skipInterleaved = " /* We have comments and */\t\n/* whitespaces*/ End of skip"; |
| assertSkipsToEndOfSkip("End of skip", skipInterleaved); |
| |
| // Skip nothing. |
| String skipNothing = "End of skip\n \t \r"; |
| assertSkipsToEndOfSkip("End of skip", skipNothing); |
| |
| // Skip everything. |
| String skipEverything = "\t/* Comment */\n\r/* And another */"; |
| assertSkipsToEndOfSkip(null, skipEverything); |
| } |
| |
| @Test |
| public void getInputLimit() { |
| // \r After 3 lines. |
| String threeLinesThen3Cr = "One Line\nThen other\rAnd finally\r\r\r"; |
| assertInputLimit("", threeLinesThen3Cr); |
| |
| // \r\r After 3 lines |
| String threeLinesThen2Cr = "One Line\nThen other\r\nAnd finally\r\r"; |
| assertInputLimit(null, threeLinesThen2Cr); |
| |
| // \n\n After 3 lines. |
| String threeLinesThen2Lf = "One Line\nThen other\r\nAnd finally\n\nFinal\n\n\nLine"; |
| assertInputLimit("Final", threeLinesThen2Lf); |
| |
| // \r\n\n After 3 lines. |
| String threeLinesThenCr2Lf = " \n \r\n \r\n\nFinal\n\n\nLine"; |
| assertInputLimit("Final", threeLinesThenCr2Lf); |
| |
| // Limit immediately. |
| String immediateEmptyLine = "\nLine\nEnd"; |
| assertInputLimit("Line", immediateEmptyLine); |
| |
| // Empty string. |
| assertInputLimit(null, ""); |
| } |
| |
| @Test |
| public void parseMethodSimpleInput() { |
| WebvttCssStyle expectedStyle = new WebvttCssStyle(); |
| String styleBlock1 = " ::cue { color : black; background-color: PapayaWhip }"; |
| expectedStyle.setFontColor(0xFF000000); |
| expectedStyle.setBackgroundColor(0xFFFFEFD5); |
| assertParserProduces(styleBlock1, expectedStyle); |
| |
| String styleBlock2 = " ::cue { color : black }\n\n::cue { color : invalid }"; |
| expectedStyle = new WebvttCssStyle(); |
| expectedStyle.setFontColor(0xFF000000); |
| assertParserProduces(styleBlock2, expectedStyle); |
| |
| String styleBlock3 = "::cue {\n background-color\n:#00fFFe}"; |
| expectedStyle = new WebvttCssStyle(); |
| expectedStyle.setBackgroundColor(0xFF00FFFE); |
| assertParserProduces(styleBlock3, expectedStyle); |
| } |
| |
| @Test |
| public void parseMethodMultipleRulesInBlockInput() { |
| String styleBlock = |
| "::cue {\n background-color\n:#00fFFe} \n::cue {\n background-color\n:#00000000}\n"; |
| WebvttCssStyle expectedStyle = new WebvttCssStyle(); |
| expectedStyle.setBackgroundColor(0xFF00FFFE); |
| WebvttCssStyle secondExpectedStyle = new WebvttCssStyle(); |
| secondExpectedStyle.setBackgroundColor(0x000000); |
| assertParserProduces(styleBlock, expectedStyle, secondExpectedStyle); |
| } |
| |
| @Test |
| public void multiplePropertiesInBlock() { |
| String styleBlock = "::cue(#id){text-decoration:underline; background-color:green;" |
| + "color:red; font-family:Courier; font-weight:bold}"; |
| WebvttCssStyle expectedStyle = new WebvttCssStyle(); |
| expectedStyle.setTargetId("id"); |
| expectedStyle.setUnderline(true); |
| expectedStyle.setBackgroundColor(0xFF008000); |
| expectedStyle.setFontColor(0xFFFF0000); |
| expectedStyle.setFontFamily("courier"); |
| expectedStyle.setBold(true); |
| |
| assertParserProduces(styleBlock, expectedStyle); |
| } |
| |
| @Test |
| public void rgbaColorExpression() { |
| String styleBlock = "::cue(#rgb){background-color: rgba(\n10/* Ugly color */,11\t, 12\n,.1);" |
| + "color:rgb(1,1,\n1)}"; |
| WebvttCssStyle expectedStyle = new WebvttCssStyle(); |
| expectedStyle.setTargetId("rgb"); |
| expectedStyle.setBackgroundColor(0x190A0B0C); |
| expectedStyle.setFontColor(0xFF010101); |
| |
| assertParserProduces(styleBlock, expectedStyle); |
| } |
| |
| @Test |
| public void getNextToken() { |
| String stringInput = " lorem:ipsum\n{dolor}#sit,amet;lorem:ipsum\r\t\f\ndolor(())\n"; |
| ParsableByteArray input = new ParsableByteArray(Util.getUtf8Bytes(stringInput)); |
| StringBuilder builder = new StringBuilder(); |
| assertThat(parseNextToken(input, builder)).isEqualTo("lorem"); |
| assertThat(parseNextToken(input, builder)).isEqualTo(":"); |
| assertThat(parseNextToken(input, builder)).isEqualTo("ipsum"); |
| assertThat(parseNextToken(input, builder)).isEqualTo("{"); |
| assertThat(parseNextToken(input, builder)).isEqualTo("dolor"); |
| assertThat(parseNextToken(input, builder)).isEqualTo("}"); |
| assertThat(parseNextToken(input, builder)).isEqualTo("#sit"); |
| assertThat(parseNextToken(input, builder)).isEqualTo(","); |
| assertThat(parseNextToken(input, builder)).isEqualTo("amet"); |
| assertThat(parseNextToken(input, builder)).isEqualTo(";"); |
| assertThat(parseNextToken(input, builder)).isEqualTo("lorem"); |
| assertThat(parseNextToken(input, builder)).isEqualTo(":"); |
| assertThat(parseNextToken(input, builder)).isEqualTo("ipsum"); |
| assertThat(parseNextToken(input, builder)).isEqualTo("dolor"); |
| assertThat(parseNextToken(input, builder)).isEqualTo("("); |
| assertThat(parseNextToken(input, builder)).isEqualTo("("); |
| assertThat(parseNextToken(input, builder)).isEqualTo(")"); |
| assertThat(parseNextToken(input, builder)).isEqualTo(")"); |
| assertThat(parseNextToken(input, builder)).isNull(); |
| } |
| |
| @Test |
| public void styleScoreSystem() { |
| WebvttCssStyle style = new WebvttCssStyle(); |
| // Universal selector. |
| assertThat(style.getSpecificityScore("", "", new String[0], "")).isEqualTo(1); |
| // Class match without tag match. |
| style.setTargetClasses(new String[] { "class1", "class2"}); |
| assertThat(style.getSpecificityScore("", "", new String[]{"class1", "class2", "class3"}, |
| "")).isEqualTo(8); |
| // Class and tag match |
| style.setTargetTagName("b"); |
| assertThat(style.getSpecificityScore("", "b", |
| new String[]{"class1", "class2", "class3"}, "")).isEqualTo(10); |
| // Class insufficiency. |
| assertThat(style.getSpecificityScore("", "b", new String[]{"class1", "class"}, "")) |
| .isEqualTo(0); |
| // Voice, classes and tag match. |
| style.setTargetVoice("Manuel Cráneo"); |
| assertThat(style.getSpecificityScore("", "b", |
| new String[]{"class1", "class2", "class3"}, "Manuel Cráneo")).isEqualTo(14); |
| // Voice mismatch. |
| assertThat(style.getSpecificityScore(null, "b", |
| new String[]{"class1", "class2", "class3"}, "Manuel Craneo")).isEqualTo(0); |
| // Id, voice, classes and tag match. |
| style.setTargetId("id"); |
| assertThat(style.getSpecificityScore("id", "b", |
| new String[]{"class1", "class2", "class3"}, "Manuel Cráneo")).isEqualTo(0x40000000 + 14); |
| // Id mismatch. |
| assertThat(style.getSpecificityScore("id1", "b", |
| new String[]{"class1", "class2", "class3"}, "")).isEqualTo(0); |
| } |
| |
| // Utility methods. |
| |
| private void assertSkipsToEndOfSkip(String expectedLine, String s) { |
| ParsableByteArray input = new ParsableByteArray(Util.getUtf8Bytes(s)); |
| CssParser.skipWhitespaceAndComments(input); |
| assertThat(input.readLine()).isEqualTo(expectedLine); |
| } |
| |
| private void assertInputLimit(String expectedLine, String s) { |
| ParsableByteArray input = new ParsableByteArray(Util.getUtf8Bytes(s)); |
| CssParser.skipStyleBlock(input); |
| assertThat(input.readLine()).isEqualTo(expectedLine); |
| } |
| |
| private void assertParserProduces(String styleBlock, WebvttCssStyle... expectedStyles) { |
| ParsableByteArray input = new ParsableByteArray(Util.getUtf8Bytes(styleBlock)); |
| List<WebvttCssStyle> styles = parser.parseBlock(input); |
| assertThat(styles.size()).isEqualTo(expectedStyles.length); |
| for (int i = 0; i < expectedStyles.length; i++) { |
| WebvttCssStyle expected = expectedStyles[i]; |
| WebvttCssStyle actualElem = styles.get(i); |
| assertThat(actualElem.hasBackgroundColor()).isEqualTo(expected.hasBackgroundColor()); |
| if (expected.hasBackgroundColor()) { |
| assertThat(actualElem.getBackgroundColor()).isEqualTo(expected.getBackgroundColor()); |
| } |
| assertThat(actualElem.hasFontColor()).isEqualTo(expected.hasFontColor()); |
| if (expected.hasFontColor()) { |
| assertThat(actualElem.getFontColor()).isEqualTo(expected.getFontColor()); |
| } |
| assertThat(actualElem.getFontFamily()).isEqualTo(expected.getFontFamily()); |
| assertThat(actualElem.getFontSize()).isEqualTo(expected.getFontSize()); |
| assertThat(actualElem.getFontSizeUnit()).isEqualTo(expected.getFontSizeUnit()); |
| assertThat(actualElem.getStyle()).isEqualTo(expected.getStyle()); |
| assertThat(actualElem.isLinethrough()).isEqualTo(expected.isLinethrough()); |
| assertThat(actualElem.isUnderline()).isEqualTo(expected.isUnderline()); |
| assertThat(actualElem.getTextAlign()).isEqualTo(expected.getTextAlign()); |
| } |
| } |
| |
| } |