[test] Added CSS parser test
This commit is contained in:
parent
c6e46b94a2
commit
0b2cf32b84
17 changed files with 1121 additions and 0 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -1,2 +1,3 @@
|
|||
harbour-books.pro.user
|
||||
tests.pro.user
|
||||
build
|
||||
|
|
21
test/Makefile
Normal file
21
test/Makefile
Normal 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
37
test/common/common.pri
Normal 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
39
test/common/stubs.cpp
Normal 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
1
test/fbreader
Symbolic link
|
@ -0,0 +1 @@
|
|||
../fbreader/
|
1
test/fribidi
Symbolic link
1
test/fribidi
Symbolic link
|
@ -0,0 +1 @@
|
|||
../fribidi/
|
1
test/harbour-lib
Symbolic link
1
test/harbour-lib
Symbolic link
|
@ -0,0 +1 @@
|
|||
../harbour-lib/
|
1
test/linebreak
Symbolic link
1
test/linebreak
Symbolic link
|
@ -0,0 +1 @@
|
|||
../linebreak/
|
32
test/test-css/data/basic/in.css
Normal file
32
test/test-css/data/basic/in.css
Normal 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
|
||||
}
|
20
test/test-css/data/basic/out.css
Normal file
20
test/test-css/data/basic/out.css
Normal 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";
|
||||
}
|
270
test/test-css/data/test1/in.css
Normal file
270
test/test-css/data/test1/in.css
Normal 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
|
||||
}
|
99
test/test-css/data/test1/out.css
Normal file
99
test/test-css/data/test1/out.css
Normal 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;
|
||||
}
|
153
test/test-css/data/test2/in.css
Normal file
153
test/test-css/data/test2/in.css
Normal 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);
|
||||
}
|
||||
|
136
test/test-css/data/test2/out.css
Normal file
136
test/test-css/data/test2/out.css
Normal 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
301
test/test-css/main.cpp
Normal 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;
|
||||
}
|
5
test/test-css/test-css.pro
Normal file
5
test/test-css/test-css.pro
Normal file
|
@ -0,0 +1,5 @@
|
|||
TARGET = test-css
|
||||
|
||||
!include(../common/common.pri)
|
||||
|
||||
SOURCES += main.cpp ../common/stubs.cpp
|
3
test/tests.pro
Normal file
3
test/tests.pro
Normal file
|
@ -0,0 +1,3 @@
|
|||
TEMPLATE = subdirs
|
||||
CONFIG += ordered
|
||||
SUBDIRS = fribidi linebreak fbreader test-css
|
Loading…
Reference in a new issue