[vlc-commits] test: add css parser

Francois Cartegnie git at videolan.org
Mon Oct 28 13:36:21 CET 2019


vlc | branch: master | Francois Cartegnie <fcvlcdev at free.fr> | Fri Oct 25 09:57:47 2019 +0200| [06cc9ec755028fc696e5491794fe71c7ace89f6e] | committer: Francois Cartegnie

test: add css parser

> http://git.videolan.org/gitweb.cgi/vlc.git/?a=commit;h=06cc9ec755028fc696e5491794fe71c7ace89f6e
---

 modules/codec/Makefile.am       |   7 +
 modules/codec/webvtt/css_test.c | 343 ++++++++++++++++++++++++++++++++++++++++
 2 files changed, 350 insertions(+)

diff --git a/modules/codec/Makefile.am b/modules/codec/Makefile.am
index 47e821dcf9..4413c0eb0e 100644
--- a/modules/codec/Makefile.am
+++ b/modules/codec/Makefile.am
@@ -236,6 +236,13 @@ libwebvtt_plugin_la_SOURCES += codec/webvtt/CSSGrammar.y \
                                codec/webvtt/css_style.c \
                                codec/webvtt/css_style.h \
                                codec/webvtt/css_bridge.h
+css_parser_test_CFLAGS = $(libwebvtt_plugin_la_CFLAGS)
+css_parser_test_SOURCES = codec/webvtt/css_test.c \
+                          codec/webvtt/css_parser.c \
+                          codec/webvtt/CSSGrammar.y \
+                          codec/webvtt/CSSLexer.l
+check_PROGRAMS += css_parser_test
+TESTS += css_parser_test
 endif
 
 libsvcdsub_plugin_la_SOURCES = codec/svcdsub.c demux/mpeg/timestamps.h
diff --git a/modules/codec/webvtt/css_test.c b/modules/codec/webvtt/css_test.c
new file mode 100644
index 0000000000..cb8ba81c2c
--- /dev/null
+++ b/modules/codec/webvtt/css_test.c
@@ -0,0 +1,343 @@
+/*****************************************************************************
+ * css_test.c: CSS Parser test
+ *****************************************************************************
+ * Copyright (C) 2019 VideoLabs, VideoLAN and VLC Authors
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation; either version 2.1 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston MA 02110-1301, USA.
+ *****************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#undef NDEBUG
+
+#include <assert.h>
+#include <vlc_common.h>
+#include "css_parser.h"
+
+#define BAILOUT(run) { fprintf(stderr, "failed %s line %d\n", run, __LINE__); \
+                        goto error; }
+#define CHECK(test) run = (test); fprintf(stderr, "* Running test %s\n", run);
+#define EXPECT(foo) if(!(foo)) BAILOUT(run)
+
+const char * css =
+        "el1 { float0: 1; }\n"
+        ".class1 { hex1: #F0000f; }\n"
+        "#id1 { text2: \"foobar\"; }\n"
+        ":pseudo { text2: \"foobar\"; }\n"
+        "attrib[foo=\"bar\"] { text2: \"foobar\"; }\n"
+        "attrib2[foo] { text2: \"foobar\"; }\n"
+        "attribincludes[foo~=\"bar\"] { text2: \"foobar\"; }\n"
+        "attribdashmatch[foo|=\"bar\"] { text2: \"foobar\"; }\n"
+        "attribstarts[foo^=\"bar\"] { text2: \"foobar\"; }\n"
+        "attribends[foo$=\"bar\"] { text2: \"foobar\"; }\n"
+        "attribcontains[foo*=\"bar\"] { text2: \"foobar\"; }\n"
+        "parent1 child1 { float0: 1; }\n"
+        "el2,el3 { float0: 1; }\n"
+        "el4+el0 { float0: 1; }\n"
+        "el5~el0 { float0: 1; }\n"
+        "el6>el0 { float0: 1; }\n"
+        "values { "
+        "  neg: -1;"
+        "  ems: 100em;"
+        "  exs: 100ex;"
+        "  pixels: 100px;"
+        "  points: 100pt; "
+        "  mm: 100mm;"
+        "  percent: 100%;"
+        "  ms: 100ms;"
+        "  hz: 100Hz;"
+        "  degrees: 100deg;"
+        "  dimension: 100 -200em 300px;"
+        "  string: \"foobar\";"
+        "  function: foo(1);"
+        "  identifier: foobar;"
+        "  hexcolor: #ff00ff;"
+        "  unicoderange: U+00-FF;"
+        "  uri: url(http://crap/);"
+        "}\n"
+;
+
+int main(void)
+{
+    const char *run ="parsing";
+    vlc_css_parser_t p;
+    vlc_css_parser_Init(&p);
+    bool b = vlc_css_parser_ParseBytes(&p, (const uint8_t *)css, strlen(css));
+    EXPECT(b);
+    vlc_css_parser_Debug(&p);
+    const vlc_css_rule_t *rule = p.rules.p_first;
+
+    CHECK("element selector");
+    EXPECT(rule && rule->b_valid);
+    EXPECT(!strcmp(rule->p_selectors->psz_name,"el1"));
+    EXPECT(rule->p_selectors->type == SELECTOR_SIMPLE);
+    const vlc_css_declaration_t *decl = rule->p_declarations;
+    EXPECT(decl && !strcmp(rule->p_declarations->psz_property, "float0"));
+    EXPECT(decl->expr && decl->expr->i_count);
+    EXPECT(decl->expr->seq[0].term.type == TYPE_NONE);
+    EXPECT(decl->expr->seq[0].term.val == 1.0);
+
+    CHECK("class selector");
+    rule = rule->p_next;
+    EXPECT(rule && rule->b_valid);
+    EXPECT(!strcmp(rule->p_selectors->psz_name,"class1"));
+    EXPECT(rule->p_selectors->type == SPECIFIER_CLASS);
+    decl = rule->p_declarations;
+    EXPECT(decl && !strcmp(rule->p_declarations->psz_property, "hex1"));
+    EXPECT(decl->expr && decl->expr->i_count);
+    EXPECT(decl->expr->seq[0].term.type == TYPE_HEXCOLOR);
+    EXPECT(!strcmp(decl->expr->seq[0].term.psz,"#F0000f"));
+
+    CHECK("id selector");
+    rule = rule->p_next;
+    EXPECT(rule && rule->b_valid);
+    EXPECT(!strcmp(rule->p_selectors->psz_name,"#id1"));
+    EXPECT(rule->p_selectors->type == SPECIFIER_ID);
+    decl = rule->p_declarations;
+    EXPECT(decl && !strcmp(rule->p_declarations->psz_property, "text2"));
+    EXPECT(decl->expr && decl->expr->i_count);
+    EXPECT(decl->expr->seq[0].term.type == TYPE_STRING);
+    EXPECT(!strcmp(decl->expr->seq[0].term.psz,"foobar"));
+
+    CHECK("pseudoclass selector");
+    rule = rule->p_next;
+    EXPECT(rule && rule->b_valid);
+    EXPECT(!strcmp(rule->p_selectors->psz_name,"pseudo"));
+    EXPECT(rule->p_selectors->type == SELECTOR_PSEUDOCLASS);
+
+    CHECK("attribute selector equals");
+    rule = rule->p_next;
+    EXPECT(rule && rule->b_valid);
+    EXPECT(!strcmp(rule->p_selectors->psz_name,"attrib"));
+    EXPECT(rule->p_selectors->type == SELECTOR_SIMPLE);
+    EXPECT(rule->p_selectors->specifiers.p_first);
+    EXPECT(rule->p_selectors->specifiers.p_first->type == SPECIFIER_ATTRIB);
+    EXPECT(!strcmp(rule->p_selectors->specifiers.p_first->psz_name, "foo"));
+    EXPECT(rule->p_selectors->specifiers.p_first->p_matchsel);
+    EXPECT(rule->p_selectors->specifiers.p_first->p_matchsel->match == MATCH_EQUALS);
+    EXPECT(!strcmp(rule->p_selectors->specifiers.p_first->p_matchsel->psz_name, "bar"));
+
+    CHECK("attribute selector key only");
+    rule = rule->p_next;
+    EXPECT(rule && rule->b_valid);
+    EXPECT(!strcmp(rule->p_selectors->psz_name,"attrib2"));
+    EXPECT(rule->p_selectors->type == SELECTOR_SIMPLE);
+    EXPECT(rule->p_selectors->specifiers.p_first);
+    EXPECT(rule->p_selectors->specifiers.p_first->type == SPECIFIER_ATTRIB);
+    EXPECT(!strcmp(rule->p_selectors->specifiers.p_first->psz_name, "foo"));
+    EXPECT(rule->p_selectors->specifiers.p_first->p_matchsel == NULL);
+
+    CHECK("attribute selector ~=");
+    rule = rule->p_next;
+    EXPECT(rule && rule->b_valid);
+    EXPECT(!strcmp(rule->p_selectors->psz_name,"attribincludes"));
+    EXPECT(rule->p_selectors->type == SELECTOR_SIMPLE);
+    EXPECT(rule->p_selectors->specifiers.p_first);
+    EXPECT(rule->p_selectors->specifiers.p_first->type == SPECIFIER_ATTRIB);
+    EXPECT(!strcmp(rule->p_selectors->specifiers.p_first->psz_name, "foo"));
+    EXPECT(rule->p_selectors->specifiers.p_first->match == MATCH_INCLUDES);
+    EXPECT(rule->p_selectors->specifiers.p_first->p_matchsel);
+    EXPECT(!strcmp(rule->p_selectors->specifiers.p_first->p_matchsel->psz_name, "bar"));
+
+    CHECK("attribute selector |=");
+    rule = rule->p_next;
+    EXPECT(rule && rule->b_valid);
+    EXPECT(!strcmp(rule->p_selectors->psz_name,"attribdashmatch"));
+    EXPECT(rule->p_selectors->type == SELECTOR_SIMPLE);
+    EXPECT(rule->p_selectors->specifiers.p_first);
+    EXPECT(rule->p_selectors->specifiers.p_first->type == SPECIFIER_ATTRIB);
+    EXPECT(!strcmp(rule->p_selectors->specifiers.p_first->psz_name, "foo"));
+    EXPECT(rule->p_selectors->specifiers.p_first->match == MATCH_DASHMATCH);
+    EXPECT(rule->p_selectors->specifiers.p_first->p_matchsel);
+    EXPECT(!strcmp(rule->p_selectors->specifiers.p_first->p_matchsel->psz_name, "bar"));
+
+    CHECK("attribute selector ^=");
+    rule = rule->p_next;
+    EXPECT(rule && rule->b_valid);
+    EXPECT(!strcmp(rule->p_selectors->psz_name,"attribstarts"));
+    EXPECT(rule->p_selectors->type == SELECTOR_SIMPLE);
+    EXPECT(rule->p_selectors->specifiers.p_first);
+    EXPECT(rule->p_selectors->specifiers.p_first->type == SPECIFIER_ATTRIB);
+    EXPECT(!strcmp(rule->p_selectors->specifiers.p_first->psz_name, "foo"));
+    EXPECT(rule->p_selectors->specifiers.p_first->match == MATCH_BEGINSWITH);
+    EXPECT(rule->p_selectors->specifiers.p_first->p_matchsel);
+    EXPECT(!strcmp(rule->p_selectors->specifiers.p_first->p_matchsel->psz_name, "bar"));
+
+    CHECK("attribute selector $=");
+    rule = rule->p_next;
+    EXPECT(rule && rule->b_valid);
+    EXPECT(!strcmp(rule->p_selectors->psz_name,"attribends"));
+    EXPECT(rule->p_selectors->type == SELECTOR_SIMPLE);
+    EXPECT(rule->p_selectors->specifiers.p_first);
+    EXPECT(rule->p_selectors->specifiers.p_first->type == SPECIFIER_ATTRIB);
+    EXPECT(!strcmp(rule->p_selectors->specifiers.p_first->psz_name, "foo"));
+    EXPECT(rule->p_selectors->specifiers.p_first->match == MATCH_ENDSWITH);
+    EXPECT(rule->p_selectors->specifiers.p_first->p_matchsel);
+    EXPECT(!strcmp(rule->p_selectors->specifiers.p_first->p_matchsel->psz_name, "bar"));
+
+    CHECK("attribute selector *=");
+    rule = rule->p_next;
+    EXPECT(rule && rule->b_valid);
+    EXPECT(!strcmp(rule->p_selectors->psz_name,"attribcontains"));
+    EXPECT(rule->p_selectors->type == SELECTOR_SIMPLE);
+    EXPECT(rule->p_selectors->specifiers.p_first);
+    EXPECT(rule->p_selectors->specifiers.p_first->type == SPECIFIER_ATTRIB);
+    EXPECT(!strcmp(rule->p_selectors->specifiers.p_first->psz_name, "foo"));
+    EXPECT(rule->p_selectors->specifiers.p_first->match == MATCH_CONTAINS);
+    EXPECT(rule->p_selectors->specifiers.p_first->p_matchsel);
+    EXPECT(!strcmp(rule->p_selectors->specifiers.p_first->p_matchsel->psz_name, "bar"));
+
+    CHECK("selectors combination parent child");
+    rule = rule->p_next;
+    EXPECT(rule && rule->b_valid);
+    EXPECT(!strcmp(rule->p_selectors->psz_name,"parent1"));
+    EXPECT(rule->p_selectors->specifiers.p_first);
+    EXPECT(rule->p_selectors->specifiers.p_first->combinator == RELATION_DESCENDENT);
+    EXPECT(!strcmp(rule->p_selectors->specifiers.p_first->psz_name, "child1"));
+
+    CHECK("selectors combination alternative");
+    rule = rule->p_next;
+    EXPECT(rule && rule->b_valid);
+    EXPECT(!strcmp(rule->p_selectors->psz_name,"el2"));
+    EXPECT(rule->p_selectors->p_next);
+    EXPECT(!strcmp(rule->p_selectors->p_next->psz_name,"el3"));
+
+    CHECK("selectors combination directadjacent");
+    rule = rule->p_next;
+    EXPECT(rule && rule->b_valid);
+    EXPECT(!strcmp(rule->p_selectors->psz_name,"el4"));
+    EXPECT(rule->p_selectors->specifiers.p_first);
+    EXPECT(rule->p_selectors->specifiers.p_first->combinator == RELATION_DIRECTADJACENT);
+    EXPECT(!strcmp(rule->p_selectors->specifiers.p_first->psz_name, "el0"));
+
+    CHECK("selectors combination directprecedent");
+    rule = rule->p_next;
+    EXPECT(rule && rule->b_valid);
+    EXPECT(!strcmp(rule->p_selectors->psz_name,"el5"));
+    EXPECT(rule->p_selectors->specifiers.p_first);
+    EXPECT(rule->p_selectors->specifiers.p_first->combinator == RELATION_INDIRECTADJACENT);
+    EXPECT(!strcmp(rule->p_selectors->specifiers.p_first->psz_name, "el0"));
+
+    CHECK("selectors combination child");
+    rule = rule->p_next;
+    EXPECT(rule && rule->b_valid);
+    EXPECT(!strcmp(rule->p_selectors->psz_name,"el6"));
+    EXPECT(rule->p_selectors->specifiers.p_first);
+    EXPECT(rule->p_selectors->specifiers.p_first->combinator == RELATION_CHILD);
+    EXPECT(!strcmp(rule->p_selectors->specifiers.p_first->psz_name, "el0"));
+
+    CHECK("values");
+    rule = rule->p_next;
+    EXPECT(rule && rule->b_valid);
+    EXPECT(!strcmp(rule->p_selectors->psz_name,"values"));
+    decl = rule->p_declarations;
+    EXPECT(decl && !strcmp(decl->psz_property, "neg"));
+    EXPECT(decl->expr && decl->expr->i_count);
+    EXPECT(decl->expr->seq[0].term.type == TYPE_NONE);
+    EXPECT(decl->expr->seq[0].term.val == -1.0);
+    decl = decl->p_next;
+    EXPECT(decl && !strcmp(decl->psz_property, "ems"));
+    EXPECT(decl->expr && decl->expr->i_count);
+    EXPECT(decl->expr->seq[0].term.type == TYPE_EMS);
+    EXPECT(decl->expr->seq[0].term.val == 100);
+    decl = decl->p_next;
+    EXPECT(decl && !strcmp(decl->psz_property, "exs"));
+    EXPECT(decl->expr && decl->expr->i_count);
+    EXPECT(decl->expr->seq[0].term.type == TYPE_EXS);
+    EXPECT(decl->expr->seq[0].term.val == 100);
+    decl = decl->p_next;
+    EXPECT(decl && !strcmp(decl->psz_property, "pixels"));
+    EXPECT(decl->expr && decl->expr->i_count);
+    EXPECT(decl->expr->seq[0].term.type == TYPE_PIXELS);
+    EXPECT(decl->expr->seq[0].term.val == 100);
+    decl = decl->p_next;
+    EXPECT(decl && !strcmp(decl->psz_property, "points"));
+    EXPECT(decl->expr && decl->expr->i_count);
+    EXPECT(decl->expr->seq[0].term.type == TYPE_POINTS);
+    EXPECT(decl->expr->seq[0].term.val == 100);
+    decl = decl->p_next;
+    EXPECT(decl && !strcmp(decl->psz_property, "mm"));
+    EXPECT(decl->expr && decl->expr->i_count);
+    EXPECT(decl->expr->seq[0].term.type == TYPE_MILLIMETERS);
+    EXPECT(decl->expr->seq[0].term.val == 100);
+    decl = decl->p_next;
+    EXPECT(decl && !strcmp(decl->psz_property, "percent"));
+    EXPECT(decl->expr && decl->expr->i_count);
+    EXPECT(decl->expr->seq[0].term.type == TYPE_PERCENT);
+    EXPECT(decl->expr->seq[0].term.val == 100);
+    decl = decl->p_next;
+    EXPECT(decl && !strcmp(decl->psz_property, "ms"));
+    EXPECT(decl->expr && decl->expr->i_count);
+    EXPECT(decl->expr->seq[0].term.type == TYPE_MILLISECONDS);
+    EXPECT(decl->expr->seq[0].term.val == 100);
+    decl = decl->p_next;
+    EXPECT(decl && !strcmp(decl->psz_property, "hz"));
+    EXPECT(decl->expr && decl->expr->i_count);
+    EXPECT(decl->expr->seq[0].term.type == TYPE_HERTZ);
+    EXPECT(decl->expr->seq[0].term.val == 100);
+    decl = decl->p_next;
+    EXPECT(decl && !strcmp(decl->psz_property, "degrees"));
+    EXPECT(decl->expr && decl->expr->i_count);
+    EXPECT(decl->expr->seq[0].term.type == TYPE_DEGREES);
+    EXPECT(decl->expr->seq[0].term.val == 100);
+    decl = decl->p_next;
+    EXPECT(decl && !strcmp(decl->psz_property, "dimension"));
+    EXPECT(decl->expr && decl->expr->i_count == 3);
+    EXPECT(decl->expr->seq[0].term.type == TYPE_NONE);
+    EXPECT(decl->expr->seq[0].term.val == 100);
+    EXPECT(decl->expr->seq[1].term.type == TYPE_EMS);
+    EXPECT(decl->expr->seq[1].term.val == -200);
+    EXPECT(decl->expr->seq[2].term.type == TYPE_PIXELS);
+    EXPECT(decl->expr->seq[2].term.val == 300);
+    decl = decl->p_next;
+    EXPECT(decl && !strcmp(decl->psz_property, "string"));
+    EXPECT(decl->expr && decl->expr->i_count);
+    EXPECT(decl->expr->seq[0].term.type == TYPE_STRING);
+    EXPECT(!strcmp(decl->expr->seq[0].term.psz, "foobar"));
+    decl = decl->p_next;
+    EXPECT(decl && !strcmp(decl->psz_property, "function"));
+    EXPECT(decl->expr && decl->expr->i_count);
+    EXPECT(decl->expr->seq[0].term.type == TYPE_FUNCTION);
+    /* todo */
+    decl = decl->p_next;
+    EXPECT(decl && !strcmp(decl->psz_property, "identifier"));
+    EXPECT(decl->expr && decl->expr->i_count);
+    EXPECT(decl->expr->seq[0].term.type == TYPE_IDENTIFIER);
+    EXPECT(!strcmp(decl->expr->seq[0].term.psz, "foobar"));
+    decl = decl->p_next;
+    EXPECT(decl && !strcmp(decl->psz_property, "hexcolor"));
+    EXPECT(decl->expr && decl->expr->i_count);
+    EXPECT(decl->expr->seq[0].term.type == TYPE_HEXCOLOR);
+    EXPECT(!strcmp(decl->expr->seq[0].term.psz, "#ff00ff"));
+    decl = decl->p_next;
+    EXPECT(decl && !strcmp(decl->psz_property, "unicoderange"));
+    EXPECT(decl->expr && decl->expr->i_count);
+    EXPECT(decl->expr->seq[0].term.type == TYPE_UNICODERANGE);
+    EXPECT(!strcmp(decl->expr->seq[0].term.psz, "U+00-FF"));
+    decl = decl->p_next;
+    EXPECT(decl && !strcmp(decl->psz_property, "uri"));
+    EXPECT(decl->expr && decl->expr->i_count);
+    EXPECT(decl->expr->seq[0].term.type == TYPE_URI);
+    EXPECT(!strcmp(decl->expr->seq[0].term.psz, "url(http://crap/)"));
+
+    vlc_css_parser_Clean(&p);
+    return 0;
+
+error:
+    vlc_css_parser_Clean(&p);
+    return 1;
+}



More information about the vlc-commits mailing list