vlc | branch: master | Francois Cartegnie <[email protected]> | 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; +} _______________________________________________ vlc-commits mailing list [email protected] https://mailman.videolan.org/listinfo/vlc-commits
