[test] Added CSS parser test

This commit is contained in:
Slava Monich 2015-08-09 12:51:26 +03:00
parent c6e46b94a2
commit 0b2cf32b84
17 changed files with 1121 additions and 0 deletions

1
.gitignore vendored
View file

@ -1,2 +1,3 @@
harbour-books.pro.user
tests.pro.user
build

21
test/Makefile Normal file
View file

@ -0,0 +1,21 @@
# -*- Mode: makefile-gmake -*-
.PHONY: all compile test test-css
BUILD_DIR = build
PATH_BACK = ..
all: build test
test: test-css
test-css: compile
@echo "====== $@ ======="
$(BUILD_DIR)/test-css/test-css -a -d test-css/data
compile: $(BUILD_DIR)
(cd $(BUILD_DIR); qmake CONFIG+=debug $(PATH_BACK)/tests.pro)
@make -C $(BUILD_DIR)
$(BUILD_DIR):
@mkdir -p $@

37
test/common/common.pri Normal file
View file

@ -0,0 +1,37 @@
CONFIG += link_pkgconfig
PKGCONFIG += glib-2.0
WARNINGS = -Wall -Wno-unused-parameter -Wno-deprecated-declarations -Wno-missing-field-initializers
QMAKE_CXXFLAGS += $$WARNINGS -Wno-psabi
QMAKE_CFLAGS += $$WARNINGS
CONFIG(debug, debug|release) {
QMAKE_CXXFLAGS_DEBUG *= -O0
QMAKE_CFLAGS_DEBUG *= -O0
DEFINES += HARBOUR_DEBUG=1
}
# Directories
FBREADER_DIR = $$_PRO_FILE_PWD_/../fbreader/fbreader
# Libraries
FBREADER_LIB = $$OUT_PWD/../fbreader/libfbreader.a
FRIBIDI_LIB = $$OUT_PWD/../fribidi/libfribidi.a
LINEBREAK_LIB = $$OUT_PWD/../linebreak/liblinebreak.a
PRE_TARGETDEPS += \
$$FBREADER_LIB \
$$FRIBIDI_LIB \
$$LINEBREAK_LIB
LIBS += \
$$FBREADER_LIB \
$$FRIBIDI_LIB \
$$LINEBREAK_LIB \
-lbz2 -lz -lexpat -lmagic
INCLUDEPATH += \
$$FBREADER_DIR/zlibrary/core/include \
$$FBREADER_DIR/zlibrary/text/include \
$$FBREADER_DIR/zlibrary/ui/src/qt4 \
$$FBREADER_DIR/fbreader/src/formats/css

39
test/common/stubs.cpp Normal file
View file

@ -0,0 +1,39 @@
/*
* Copyright (C) 2015 Jolla Ltd.
* Contact: Slava Monich <slava.monich@jolla.com>
*
* You may use this file under the terms of the BSD license as follows:
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * 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.
* * Neither the name of Nemo Mobile 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
* OWNER 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 "ZLExecutionData.h"
#include "ZLibrary.h"
#include "ZLImage.h"
const std::string ZLibrary::FileNameDelimiter("/");
std::string ZLibrary::ourZLibraryDirectory(".");

1
test/fbreader Symbolic link
View file

@ -0,0 +1 @@
../fbreader/

1
test/fribidi Symbolic link
View file

@ -0,0 +1 @@
../fribidi/

1
test/harbour-lib Symbolic link
View file

@ -0,0 +1 @@
../harbour-lib/

1
test/linebreak Symbolic link
View file

@ -0,0 +1 @@
../linebreak/

View file

@ -0,0 +1,32 @@
/* Basic tests */
/* 1. DOS-style EOL */
/* 2. Ignore AT-rules */
@foo { foo: bar; }
@font-face {
font-family: "foo";
src: url(fonts/bar.ttf);
}
/* 3. Multi
line
comment */
/* 4. Comment within a statement */
body,h1,h2, /*///****/ div, p {
/* 5. Empty line */
/* 6. Unknown attribute */
unknown-attribute: unknown-value;
/* 7. Extra semicolon */
extra: semicolon;;
/* 8. Missing attribute name */
: missing-attribute-name;
/* 9. Missing colon */
missing-colon
/* 10. Missing semicolon */
missing: semicolon
font-family: \
/* 11. Multi-line statement */ \
"Foo\
Bar";
/* 12: Known style with missing semicolon */
font-style: italic
}

View file

@ -0,0 +1,20 @@
body {
font-style: italic;
font-family: "Foo Bar";
}
h1 {
font-style: italic;
font-family: "Foo Bar";
}
h2 {
font-style: italic;
font-family: "Foo Bar";
}
div {
font-style: italic;
font-family: "Foo Bar";
}
p {
font-style: italic;
font-family: "Foo Bar";
}

View file

@ -0,0 +1,270 @@
.alert {
-moz-box-sizing: border-box;
box-sizing: border-box;
display: block
}
.book-chapter {
-moz-box-sizing: border-box;
box-sizing: border-box;
display: none;
font-size: 2em;
font-weight: bold;
line-height: 1.2;
padding-bottom: 0.3em;
position: relative;
border-bottom: #eee solid 1px;
margin: 1em 0 16px
}
.calibre {
display: block;
font-size: 1em;
padding-left: 0;
padding-right: 0;
margin: 0 5pt
}
.calibre1 {
display: none
}
.calibre2 {
-moz-box-sizing: border-box;
box-sizing: border-box;
display: block;
font-size: 2em;
font-weight: bold;
line-height: 1.2;
padding-bottom: 0.3em;
position: relative;
border-bottom: #eee solid 1px;
margin: 1em 0 16px
}
.calibre3 {
-moz-box-sizing: border-box;
box-sizing: border-box;
display: block;
font-size: 1.83333em;
font-weight: bold;
line-height: 1.2;
padding-bottom: 0.3em;
position: relative;
border-bottom: #eee solid 1px;
margin: 1em 0 16px
}
.calibre4 {
-moz-box-sizing: border-box;
box-sizing: border-box;
display: block;
margin: 0 0 16px
}
.calibre5 {
-moz-box-sizing: border-box;
box-sizing: border-box;
font-style: italic
}
.calibre6 {
-moz-box-sizing: border-box;
background: transparent;
box-sizing: border-box;
color: #4183c4;
text-decoration: none
}
.calibre7 {
-moz-box-sizing: border-box;
box-sizing: border-box;
height: auto;
max-width: 100%;
page-break-inside: avoid;
width: auto;
border: currentColor none 0
}
.calibre8 {
-moz-box-sizing: border-box;
box-sizing: border-box;
font-weight: bold
}
.calibre9 {
-moz-box-sizing: border-box;
background-color: #f7f7f7;
border-radius: 3px;
box-sizing: border-box;
font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace;
font-size: 0.75em;
padding: 0.2em 0;
margin: 0
}
.calibre10 {
-moz-box-sizing: border-box;
background-color: #f7f7f7;
border-radius: 3px;
box-sizing: border-box;
display: block;
font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace;
font-size: 0.75em;
line-height: 1.45;
overflow: auto;
white-space: pre-wrap;
word-wrap: normal;
padding: 16px;
border: currentColor none 0;
margin: 0 0 16px
}
.calibre11 {
-moz-box-sizing: border-box;
box-sizing: border-box;
display: table-row-group;
vertical-align: middle
}
.calibre12 {
-moz-box-sizing: border-box;
background-color: #fff;
box-sizing: border-box;
display: table-row;
vertical-align: inherit;
border-top: #ccc solid 1px
}
.calibre13 {
-moz-box-sizing: border-box;
box-sizing: border-box;
display: table-cell;
text-align: inherit;
vertical-align: inherit;
padding: 6px 13px;
border: #ddd solid 1px
}
.calibre14 {
-moz-box-sizing: border-box;
background-color: #f8f8f8;
box-sizing: border-box;
display: table-row;
vertical-align: inherit;
border-top: #ccc solid 1px
}
.calibre15 {
-moz-box-sizing: border-box;
box-sizing: border-box;
display: block;
font-size: 1.41667em;
font-weight: bold;
line-height: 1.43;
position: relative;
margin: 1em 0 16px
}
.hljs-comment {
-moz-box-sizing: border-box;
box-sizing: border-box;
color: #8e908c
}
.hljs-keyword {
-moz-box-sizing: border-box;
box-sizing: border-box;
color: #8959a8
}
.hljs-preprocessor {
-moz-box-sizing: border-box;
box-sizing: border-box;
color: #f5871f
}
.hljs-string {
-moz-box-sizing: border-box;
box-sizing: border-box;
color: #718c00
}
.lang-c {
-moz-box-sizing: border-box;
background: transparent;
background-color: transparent;
border-radius: 3px;
box-sizing: border-box;
display: inline;
font-family: Consolas, "Liberation Mono", Menlo, Courier, monospace;
font-size: 1em;
line-height: inherit;
max-width: initial;
overflow: initial;
white-space: pre-wrap;
word-wrap: normal;
padding: 0;
border: currentColor none 0;
margin: 0
}
.list-group {
-moz-box-sizing: border-box;
box-sizing: border-box;
display: block;
list-style-type: disc;
margin-bottom: 16px;
margin-right: 0;
margin-top: 0;
padding-bottom: 0;
padding-right: 0;
padding-top: 0
}
.list-group-item {
-moz-box-sizing: border-box;
box-sizing: border-box;
display: list-item
}
.normal {
-moz-box-sizing: border-box;
box-sizing: border-box
}
.page {
-ms-text-size-adjust: 100%;
-webkit-text-size-adjust: 100%;
color: #333;
display: block;
font-family: sans-serif;
line-height: 1.6;
overflow: hidden;
word-wrap: break-word
}
.table {
-moz-box-sizing: border-box;
border-collapse: collapse;
border-spacing: 0;
box-sizing: border-box;
display: block;
margin-bottom: 16px;
margin-top: 0;
overflow: auto;
text-indent: 0;
width: 100%
}
.table1 {
-moz-box-sizing: border-box;
border-collapse: collapse;
border-spacing: 0;
box-sizing: border-box;
display: inline;
margin-bottom: 16px;
margin-top: 0;
overflow: auto;
text-indent: 0;
width: 100%
}
.pcalibre2:focus {
text-decoration: underline
}
.pcalibre3:after {
content: " ";
letter-spacing: -0.2em
}
.pcalibre5:after {
content: normal;
letter-spacing: -0.2em
}
.pcalibre4:before {
content: " ";
letter-spacing: -0.2em
}
.pcalibre6:before {
content: normal;
letter-spacing: -0.2em
}
.pcalibre1:hover {
outline: 0;
text-decoration: underline
}
.pcalibre:active {
outline: 0;
text-decoration: underline
}

View file

@ -0,0 +1,99 @@
.book-chapter {
margin-left: 0;
margin-bottom: 16px;
margin-top: 1em;
margin-right: 0;
display: none;
font-weight: bold;
font-size: 207%; /* 4 */
}
.calibre {
margin-left: 5px;
margin-bottom: 0;
margin-top: 0;
margin-right: 5px;
font-size: 100%; /* 0 */
}
.calibre1 {
display: none;
}
.calibre2 {
margin-left: 0;
margin-bottom: 16px;
margin-top: 1em;
margin-right: 0;
font-weight: bold;
font-size: 207%; /* 4 */
}
.calibre3 {
margin-left: 0;
margin-bottom: 16px;
margin-top: 1em;
margin-right: 0;
font-weight: bold;
font-size: 207%; /* 4 */
}
.calibre4 {
margin-left: 0;
margin-bottom: 16px;
margin-top: 0;
margin-right: 0;
}
.calibre5 {
font-style: italic;
}
.calibre8 {
font-weight: bold;
}
.calibre9 {
margin-left: 0;
margin-bottom: 0;
margin-top: 0;
margin-right: 0;
font-family: "Consolas", "Liberation Mono", "Menlo", "Courier", "monospace";
font-size: 83%; /* -1 */
}
.calibre10 {
margin-left: 0;
margin-bottom: 16px;
margin-top: 0;
margin-right: 0;
white-space: pre-wrap;
font-family: "Consolas", "Liberation Mono", "Menlo", "Courier", "monospace";
font-size: 83%; /* -1 */
}
.calibre15 {
margin-left: 0;
margin-bottom: 16px;
margin-top: 1em;
margin-right: 0;
font-weight: bold;
font-size: 144%; /* 2 */
}
.lang-c {
margin-left: 0;
margin-bottom: 0;
margin-top: 0;
margin-right: 0;
white-space: pre-wrap;
font-family: "Consolas", "Liberation Mono", "Menlo", "Courier", "monospace";
font-size: 100%; /* 0 */
}
.list-group {
margin-bottom: 16px;
margin-top: 0;
margin-right: 0;
}
.page {
font-family: "sans-serif";
}
.table {
margin-bottom: 16px;
margin-top: 0;
text-indent: 0;
}
.table1 {
margin-bottom: 16px;
margin-top: 0;
text-indent: 0;
}

View file

@ -0,0 +1,153 @@
body.cover {
margin: 0px;
oeb-column-number: 1;
padding: 0px;
}
svg.cover-svg {
height: 100%;
width: 100%;
}
.z {
font-family: 'Times New Roman', serif;
margin-right: 8pt;
}
.title {
font-size: 2.2em;
font-weight: bold;
margin: 1em 0px 0.5em 0px;
page-break-after: avoid;
page-break-inside: avoid;
text-align: center;
}
.p {
margin: 0px 0px 0.5em 0px;
text-align: inherit;
text-indent: 0px;
}
.epigraph {
font-style: italic;
margin: 1em 1em 2em 30%;
text-align: left;
}
.p1 {
margin: 0px;
text-align: justify;
text-indent: 1.5em;
}
.text-author {
margin: 0.2em 0px 0px 3em;
text-indent: 0px;
}
.title1 {
font-size: 1.8em;
font-weight: bold;
margin: 1em 0px 0.5em 0px;
page-break-after: avoid;
page-break-inside: avoid;
text-align: center;
}
.title2 {
font-size: 1.5em;
font-weight: bold;
margin: 1em 0px 0.5em 1.563em;
page-break-after: avoid;
page-break-inside: avoid;
text-align: left;
}
.empty-line {
height: 1em;
margin: 0px;
}
.a {
font-size: 0.7em;
line-height: 0.1;
vertical-align: super;
}
.poem {
margin: 0.5em 0px 0.5em 2em;
}
.stanza {
margin: 0.5em 0px;
page-break-inside: avoid;
}
.v {
margin: 0px;
padding-left: 1em;
text-indent: -1em;
}
.subtitle {
font-style: italic;
font-weight: bold;
margin: 0.5em 2em;
page-break-after: avoid;
page-break-inside: avoid;
text-align: center;
text-indent: 0px;
}
.title3 {
font-size: 1.3em;
font-weight: bold;
margin: 1em 0px 0.5em 1.923em;
page-break-after: avoid;
page-break-inside: avoid;
text-align: left;
}
.cite {
font-size: 0.95em;
margin: 0.5em 0px 0.5em 1em;
}
.title4 {
font-size: 1.2em;
font-weight: bold;
margin: 1em 0px 0.5em 2.083em;
page-break-after: avoid;
page-break-inside: avoid;
text-align: left;
}
@font-face {
font-family: 'Times New Roman';
font-style: italic;
font-weight: normal;
src: url(fonts/Times-New-Roman-400-Italic-0dc9cb1e-1e51-102b-9d2a-1f07c3bd69d8.otf);
}
@font-face {
font-family: 'Times New Roman';
font-style: normal;
font-weight: normal;
src: url(fonts/Times-New-Roman-400-0dc9cb1e-1e51-102b-9d2a-1f07c3bd69d8.otf);
}
@font-face {
font-family: 'Times New Roman';
font-style: italic;
font-weight: bold;
src: url(fonts/Times-New-Roman-700-Italic-0dc9cb1e-1e51-102b-9d2a-1f07c3bd69d8.otf);
}
@font-face {
font-family: 'Times New Roman';
font-style: normal;
font-weight: bold;
src: url(fonts/Times-New-Roman-700-0dc9cb1e-1e51-102b-9d2a-1f07c3bd69d8.otf);
}

View file

@ -0,0 +1,136 @@
body.cover {
margin-left: 0;
margin-bottom: 0;
margin-top: 0;
margin-right: 0;
}
.z {
margin-right: 8px;
font-family: "Times New Roman", "serif";
}
.title {
margin-left: 0;
margin-bottom: 0.5em;
margin-top: 1em;
margin-right: 0;
page-break-before: avoid;
text-align: center;
font-weight: bold;
font-size: 248%; /* 5 */
}
.p {
margin-left: 0;
margin-bottom: 0.5em;
margin-top: 0;
margin-right: 0;
text-indent: 0;
}
.epigraph {
margin-left: 30%;
margin-bottom: 2em;
margin-top: 1em;
margin-right: 1em;
text-align: left;
font-style: italic;
}
.p1 {
margin-left: 0;
margin-bottom: 0;
margin-top: 0;
margin-right: 0;
text-indent: 1.5em;
text-align: justify;
}
.text-author {
margin-left: 3em;
margin-bottom: 0;
margin-top: 0.2em;
margin-right: 0;
text-indent: 0;
}
.title1 {
margin-left: 0;
margin-bottom: 0.5em;
margin-top: 1em;
margin-right: 0;
page-break-before: avoid;
text-align: center;
font-weight: bold;
font-size: 207%; /* 4 */
}
.title2 {
margin-left: 1.56em;
margin-bottom: 0.5em;
margin-top: 1em;
margin-right: 0;
page-break-before: avoid;
text-align: left;
font-weight: bold;
font-size: 172%; /* 3 */
}
.empty-line {
margin-left: 0;
margin-bottom: 0;
margin-top: 0;
margin-right: 0;
}
.a {
font-size: 83%; /* -1 */
}
.poem {
margin-left: 2em;
margin-bottom: 0.5em;
margin-top: 0.5em;
margin-right: 0;
}
.stanza {
margin-left: 0;
margin-bottom: 0.5em;
margin-top: 0.5em;
margin-right: 0;
}
.v {
margin-left: 0;
margin-bottom: 0;
margin-top: 0;
margin-right: 0;
text-indent: -1em;
}
.subtitle {
margin-left: 2em;
margin-bottom: 0.5em;
margin-top: 0.5em;
margin-right: 2em;
text-indent: 0;
page-break-before: avoid;
text-align: center;
font-weight: bold;
font-style: italic;
}
.title3 {
margin-left: 1.92em;
margin-bottom: 0.5em;
margin-top: 1em;
margin-right: 0;
page-break-before: avoid;
text-align: left;
font-weight: bold;
font-size: 144%; /* 2 */
}
.cite {
margin-left: 1em;
margin-bottom: 0.5em;
margin-top: 0.5em;
margin-right: 0;
font-size: 83%; /* -1 */
}
.title4 {
margin-left: 2.08em;
margin-bottom: 0.5em;
margin-top: 1em;
margin-right: 0;
page-break-before: avoid;
text-align: left;
font-weight: bold;
font-size: 120%; /* 1 */
}

301
test/test-css/main.cpp Normal file
View file

@ -0,0 +1,301 @@
/*
* Copyright (C) 2015 Jolla Ltd.
* Contact: Slava Monich <slava.monich@jolla.com>
*
* You may use this file under the terms of the BSD license as follows:
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
*
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * 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.
* * Neither the name of Nemo Mobile 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
* OWNER 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 <glib.h>
#define private public
#include "StyleSheetParser.h"
#undef private
#include "ZLInputStream.h"
#include "ZLStringUtil.h"
#include "ZLFile.h"
#include "filesystem/ZLQtFSManager.h"
#include <iostream>
#include <fstream>
#include <sstream>
#define RET_OK (0)
#define RET_CMD_LINE (1)
#define RET_ERR_IO (2)
#define RET_ERR_TEST (3)
static void
dumpLength(
const ZLTextStyleEntry& entry,
ZLTextStyleEntry::Length type,
const char* name,
std::ostream& out)
{
if (entry.lengthSupported(type)) {
const ZLTextStyleEntry::LengthType* length = entry.myLengths + type;
out << " " << name << ": ";
if (!length->Size) {
out << "0";
} else {
switch (entry.myLengths[type].Unit) {
case ZLTextStyleEntry::SIZE_UNIT_PIXEL:
out << length->Size << "px";
break;
case ZLTextStyleEntry::SIZE_UNIT_EM_100:
out << length->Size/100. << "em";
break;
case ZLTextStyleEntry::SIZE_UNIT_EX_100:
out << length->Size/100. << "ex";
break;
case ZLTextStyleEntry::SIZE_UNIT_PERCENT:
out << length->Size << "%";
break;
}
}
out << ";\n";
}
}
static void
dumpStyle(
const StyleSheetTable::Style& style,
std::ostream& out)
{
dumpLength(style.TextStyle, ZLTextStyleEntry::LENGTH_LEFT_INDENT, "margin-left", out);
dumpLength(style.TextStyle, ZLTextStyleEntry::LENGTH_SPACE_AFTER, "margin-bottom", out);
dumpLength(style.TextStyle, ZLTextStyleEntry::LENGTH_SPACE_BEFORE, "margin-top", out);
dumpLength(style.TextStyle, ZLTextStyleEntry::LENGTH_RIGHT_INDENT, "margin-right", out);
dumpLength(style.TextStyle, ZLTextStyleEntry::LENGTH_FIRST_LINE_INDENT_DELTA, "text-indent", out);
if (style.PageBreakBefore != B3_UNDEFINED) {
out << " page-break-before: " <<
((style.PageBreakBefore == B3_TRUE) ? "always" : "avoid") << ";\n";
}
if (style.PageBreakAfter != B3_UNDEFINED) {
out << " page-break-before: " <<
((style.PageBreakAfter == B3_TRUE) ? "always" : "avoid") << ";\n";
}
if (style.WhiteSpace != StyleSheetTable::WS_UNDEFINED) {
static const char* values[] = {NULL, "normal", "nowrap", "pre", "pre-wrap", "pre-line" };
out << " white-space: " << values[style.WhiteSpace] << ";\n";
}
if (style.DisplayNone) {
out << " display: none;\n";
}
if (style.TextStyle.alignmentTypeSupported()) {
const char* align;
switch (style.TextStyle.alignmentType()) {
case ALIGN_LEFT: align = "left"; break;
case ALIGN_RIGHT: align = "right"; break;
case ALIGN_CENTER: align = "center"; break;
case ALIGN_JUSTIFY: align = "justify"; break;
default: align = NULL; break;
}
if (align) {
out << " text-align: " << align << ";\n";
}
}
const unsigned char supMod = style.TextStyle.supportedFontModifier();
const unsigned char mod = style.TextStyle.fontModifier();
if (supMod & FONT_MODIFIER_BOLD) {
out << " font-weight: " <<
((mod & FONT_MODIFIER_BOLD) ? "bold" : "normal") << ";\n";
}
if (supMod & FONT_MODIFIER_ITALIC) {
out << " font-style: " <<
((mod & FONT_MODIFIER_ITALIC) ? "italic" : "normal") << ";\n";
}
if (supMod & FONT_MODIFIER_SMALLCAPS) {
out << " font-variant: " <<
((mod & FONT_MODIFIER_SMALLCAPS) ? "small-caps" : "normal") << ";\n";
}
if (style.TextStyle.fontFamiliesSupported()) {
const std::vector<std::string>& fonts = style.TextStyle.fontFamilies();
if (!fonts.empty()) {
out << " font-family: ";
std::vector<std::string>::const_iterator it;
for (it = fonts.begin(); it != fonts.end(); ++it) {
if (it != fonts.begin()) out << ", ";
out << "\"" << *it << "\"";
}
out << ";\n";
}
}
if (style.TextStyle.fontSizeSupported()) {
out << " font-size: ";
const signed char mag = style.TextStyle.fontSizeMag();
int size = 100;
if (mag >= 0) {
for (int i = 0; i < mag; ++i) size *= 6;
for (int i = 0; i < mag; ++i) size /= 5;
} else {
for (int i = 0; i > mag; --i) size *= 5;
for (int i = 0; i > mag; --i) size /= 6;
}
out << size << "%; /* " << ((int)mag) << " */\n";
}
}
static void
dumpTable(
const StyleSheetTable& table,
std::ostream& out)
{
std::vector<StyleSheetTable::Entry>::const_iterator it;
for (it = table.myEntries.begin(); it != table.myEntries.end(); ++it) {
const StyleSheetTable::Entry& entry = *it;
StyleSheetTable::SelectorList::const_iterator sit;
for (sit = entry.Selectors.begin(); sit != entry.Selectors.end(); ++sit) {
const StyleSheetTable::Selector& selector = *sit;
out << selector.myType;
if (!selector.myClass.empty()) out << "." << selector.myClass;
if (!selector.myId.empty()) out << "#" << selector.myId;
out << " ";
}
out << "{\n";
dumpStyle(entry.Style, out);
out << "}\n";
}
}
static int
process_file(
std::string fname,
std::ostream& out)
{
ZLFile file(fname);
shared_ptr<ZLInputStream> stream = file.inputStream();
if (!stream.isNull() && stream->open()) {
StyleSheetTable table;
StyleSheetTableParser parser(table);
parser.parse(*stream);
dumpTable(table, out);
return RET_OK;
} else {
std::cerr << "Failed to open " << fname << std::endl;
return RET_ERR_IO;
}
}
static int
process(
std::string name)
{
int ret;
ZLFile file(name);
if (file.isDirectory()) {
std::string in(name + "/in.css");
std::string res(name + "/out.css");
std::ostringstream out;
ret = process_file(in, out);
if (ret == RET_OK) {
std::ifstream fres(res.c_str());
if (fres) {
std::stringstream buf;
buf << fres.rdbuf();
fres.close();
if (buf.str() != out.str()) {
std::cerr << "Test output mismatch with " << res << std::endl;
//std::cerr << out.str();
ret = RET_ERR_TEST;
}
} else {
std::cerr << "Failed to open " << res << std::endl;
ret = RET_ERR_IO;
}
}
std::cerr << ((ret == RET_OK) ? "OK" : "FAIL") << ": " << name << std::endl;
} else {
ret = process_file(name, std::cout);
}
return ret;
}
int main(int argc, char **argv)
{
int ret;
char* customDataDir = NULL;
gboolean autoTest = FALSE;
#define DATA_DIR "data"
GOptionEntry entries[] = {
{ "autotest", 'a', 0, G_OPTION_ARG_NONE, &autoTest,
"Run auto-tests", NULL },
{ "data", 'd', 0, G_OPTION_ARG_FILENAME, &customDataDir,
"Data directory for autotest [" DATA_DIR "]", "DIR" },
{ NULL }
};
GError* error = NULL;
GOptionContext* options = g_option_context_new("- CSS parsing test");
g_option_context_add_main_entries(options, entries, NULL);
gboolean ok = g_option_context_parse(options, &argc, &argv, &error);
if (ok) {
if (argc == 1 && !autoTest) {
ret = RET_CMD_LINE;
char* help = g_option_context_get_help(options, FALSE, NULL);
std::cout << help;
g_free(help);
} else {
ret = RET_OK;
ZLQtFSManager::createInstance();
if (argc > 1) {
for (int i=1; i<argc; i++) {
const int ret2 = process(argv[i]);
if (ret2 != RET_OK && ret == RET_OK) ret = ret2;
}
}
if (autoTest) {
static const char* tests[] = {
"basic",
"test1",
"test2"
};
std::string dataDir(customDataDir ? customDataDir : DATA_DIR);
if (!ZLStringUtil::stringEndsWith(dataDir, "/")) dataDir += "/";
for (unsigned int i=0; i<(sizeof(tests)/sizeof(tests[0])); i++) {
const int ret2 = process(dataDir + tests[i]);
if (ret2 != RET_OK && ret == RET_OK) ret = ret2;
}
}
ZLFSManager::deleteInstance();
}
} else {
std::cerr << error->message << std::endl;
g_error_free(error);
ret = RET_CMD_LINE;
}
g_option_context_free(options);
g_free(customDataDir);
return ret;
}

View file

@ -0,0 +1,5 @@
TARGET = test-css
!include(../common/common.pri)
SOURCES += main.cpp ../common/stubs.cpp

3
test/tests.pro Normal file
View file

@ -0,0 +1,3 @@
TEMPLATE = subdirs
CONFIG += ordered
SUBDIRS = fribidi linebreak fbreader test-css