diff options
author | Norbert Preining <norbert@preining.info> | 2019-09-02 13:46:59 +0900 |
---|---|---|
committer | Norbert Preining <norbert@preining.info> | 2019-09-02 13:46:59 +0900 |
commit | e0c6872cf40896c7be36b11dcc744620f10adf1d (patch) | |
tree | 60335e10d2f4354b0674ec22d7b53f0f8abee672 /dviware/dvisvgm/tests/PDFParserTest.cpp |
Initial commit
Diffstat (limited to 'dviware/dvisvgm/tests/PDFParserTest.cpp')
-rw-r--r-- | dviware/dvisvgm/tests/PDFParserTest.cpp | 239 |
1 files changed, 239 insertions, 0 deletions
diff --git a/dviware/dvisvgm/tests/PDFParserTest.cpp b/dviware/dvisvgm/tests/PDFParserTest.cpp new file mode 100644 index 0000000000..58e879c7e0 --- /dev/null +++ b/dviware/dvisvgm/tests/PDFParserTest.cpp @@ -0,0 +1,239 @@ +/************************************************************************* +** PDFParserTest.cpp ** +** ** +** This file is part of dvisvgm -- a fast DVI to SVG converter ** +** Copyright (C) 2005-2019 Martin Gieseking <martin.gieseking@uos.de> ** +** ** +** This program is free software; you can redistribute it and/or ** +** modify it under the terms of the GNU General Public License as ** +** published by the Free Software Foundation; either version 3 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 General Public License for more details. ** +** ** +** You should have received a copy of the GNU General Public License ** +** along with this program; if not, see <http://www.gnu.org/licenses/>. ** +*************************************************************************/ + +#include <gtest/gtest.h> +#include "PDFParser.hpp" + +using namespace std; + +TEST(PDFParserTest, empty) { + PDFParser parser; + vector<PDFObject> objects = parser.parse(""); + EXPECT_TRUE(objects.empty()); + objects = parser.parse(" \n \r %comment 1 2 3 "); + EXPECT_TRUE(objects.empty()); +} + + +TEST(PDFParserTest, numbers) { + PDFParser parser; + vector<PDFObject> objects = parser.parse("5 1 +2 -3 1.1 9. .1 -7.2"); + ASSERT_EQ(objects.size(), 8u); + + size_t count=0; + for (int n : {5, 1, 2, -3}) { + ASSERT_NE(objects[count].get<int>(), nullptr); + EXPECT_EQ(*objects[count++].get<int>(), n); + } + for (double n : {1.1, 9.0, 0.1, -7.2}) { + ASSERT_NE(objects[count].get<double>(), nullptr); + EXPECT_DOUBLE_EQ(*objects[count++].get<double>(), n); + } +} + + +TEST(PDFParserTest, literal_strings) { + PDFParser parser; + vector<PDFObject> objects = parser.parse("()"); + ASSERT_EQ(objects.size(), 1u); + ASSERT_NE(objects[0].get<string>(), nullptr); + EXPECT_TRUE(objects[0].get<string>()->empty()); + + objects = parser.parse("(literal string) (balanced (bra(ck)ets) inside)(a\\n\\(b\\c)"); + ASSERT_EQ(objects.size(), 3u); + + size_t count=0; + for (string str : {"literal string", "balanced (bra(ck)ets) inside", "a\n(bc"}) { + ASSERT_NE(objects[count].get<string>(), nullptr); + ASSERT_EQ(*objects[count++].get<string>(), str); + } + + objects = parser.parse(R"*( ( octal \1\12\123\1234 ))*"); + ASSERT_EQ(objects.size(), 1u); + ASSERT_NE(objects[0].get<string>(), nullptr); + EXPECT_EQ(objects[0].get<string>()->size(), 13u); + EXPECT_EQ(*objects[0].get<string>(), " octal \001\012\123\1234 "); + + objects = parser.parse("(split \\\nline)"); + ASSERT_EQ(objects.size(), 1u); + ASSERT_NE(objects[0].get<string>(), nullptr); + EXPECT_EQ(*objects[0].get<string>(), "split line"); + + EXPECT_THROW(parser.parse("(missing parentheses"), PDFException); +} + + +TEST(PDFParserTest, hex_strings) { + PDFParser parser; + vector<PDFObject> objects = parser.parse("<>< ><\n\r\f>"); + ASSERT_EQ(objects.size(), 3u); + for (size_t i=0; i < objects.size(); i++) { + ASSERT_NE(objects[i].get<string>(), nullptr); + EXPECT_TRUE(objects[i].get<string>()->empty()); + } + + objects = parser.parse("<202>"); + ASSERT_EQ(objects.size(), 1u); + ASSERT_NE(objects[0].get<string>(), nullptr); + EXPECT_EQ(*objects[0].get<string>(), " "); + + objects = parser.parse("<616263646566 6768\n696A6b6c6D6E6F 7>"); + ASSERT_EQ(objects.size(), 1u); + ASSERT_NE(objects[0].get<string>(), nullptr); + EXPECT_EQ(*objects[0].get<string>(), "abcdefghijklmnop"); + + EXPECT_THROW(parser.parse("<abcdefinvalid>"), PDFException); + EXPECT_THROW(parser.parse("<missing parentheses"), PDFException); +} + + +TEST(PDFParserTest, arrays) { + PDFParser parser; + vector<PDFObject> objects = parser.parse("[1 2.0/name(string) [5] <6162>]"); + ASSERT_EQ(objects.size(), 1u); + const PDFArray *arr = objects[0].get<PDFArray>(); + ASSERT_NE(arr, nullptr); + ASSERT_EQ(arr->size(), 6u); + + // integer number + ASSERT_NE((*arr)[0].get<int>(), nullptr); + ASSERT_EQ(*(*arr)[0].get<int>(), 1); + + // real number + ASSERT_NE((*arr)[1].get<double>(), nullptr); + ASSERT_DOUBLE_EQ(*(*arr)[1].get<double>(), 2.0); + + // name + ASSERT_NE((*arr)[2].get<PDFName>(), nullptr); + ASSERT_EQ(*(*arr)[2].get<PDFName>(), PDFName("name")); + + // literal string + ASSERT_NE((*arr)[3].get<string>(), nullptr); + ASSERT_EQ(*(*arr)[3].get<string>(), "string"); + + // inner array + ASSERT_NE((*arr)[4].get<PDFArray>(), nullptr); + ASSERT_EQ((*arr)[4].get<PDFArray>()->size(), 1u); + ASSERT_NE((*arr)[4].get<PDFArray>()->at(0).get<int>(), nullptr); + ASSERT_EQ(*(*arr)[4].get<PDFArray>()->at(0).get<int>(), 5); + + // hex string + ASSERT_NE((*arr)[5].get<string>(), nullptr); + ASSERT_EQ(*(*arr)[5].get<string>(), "ab"); +} + + +TEST(PDFParserTest, dictionary) { + PDFParser parser; + vector<PDFObject> objects = parser.parse("<< >>"); + ASSERT_EQ(objects.size(), 1u); + const PDFDict *dict = objects[0].get<PDFDict>(); + ASSERT_NE(dict, nullptr); + ASSERT_TRUE(dict->empty()); + + objects = parser.parse("<</int 4 /real 5.5/str(string value)/color[0 1 1]>>"); + ASSERT_EQ(objects.size(), 1u); + dict = objects[0].get<PDFDict>(); + ASSERT_NE(dict, nullptr); + ASSERT_EQ(dict->size(), 4u); + + // integer number + ASSERT_NE(dict->find("int"), dict->end()); + ASSERT_NE(dict->find("int")->second.get<int>(), nullptr); + EXPECT_EQ(*dict->find("int")->second.get<int>(), 4); + + ASSERT_NE(dict->find("real"), dict->end()); + ASSERT_NE(dict->find("real")->second.get<double>(), nullptr); + EXPECT_DOUBLE_EQ(*dict->find("real")->second.get<double>(), 5.5); + + ASSERT_NE(dict->find("str"), dict->end()); + ASSERT_NE(dict->find("str")->second.get<string>(), nullptr); + EXPECT_EQ(*dict->find("str")->second.get<string>(), "string value"); + + ASSERT_NE(dict->find("color"), dict->end()); + ASSERT_NE(dict->find("color")->second.get<PDFArray>(), nullptr); + const PDFArray &arr = *dict->find("color")->second.get<PDFArray>(); + ASSERT_EQ(arr.size(), 3u); + EXPECT_EQ(*arr[0].get<int>(), 0); + EXPECT_EQ(*arr[1].get<int>(), 1); + EXPECT_EQ(*arr[2].get<int>(), 1); + + EXPECT_EQ(dict->find("nokey"), dict->end()); + + EXPECT_THROW(parser.parse("<</int >>"), PDFException); // missing value + EXPECT_THROW(parser.parse("<</int 4>"), PDFException); // missing ">" + EXPECT_THROW(parser.parse("<</int 4"), PDFException); // missing ">>" +} + + +TEST(PDFParserTest, indirect_objects) { + PDFParser parser; + vector<PDFObject> objects = parser.parse("1 0 obj\n1 2 3 4 5endobj 2 5 R"); + ASSERT_EQ(objects.size(), 2u); + ASSERT_NE(objects[0].get<PDFIndirectObject>(), nullptr); + EXPECT_EQ(objects[0].get<PDFIndirectObject>()->objnum, 1); + EXPECT_EQ(objects[0].get<PDFIndirectObject>()->gennum, 0); + + ASSERT_NE(objects[1].get<PDFObjectRef>(), nullptr); + EXPECT_EQ(objects[1].get<PDFObjectRef>()->objnum, 2); + EXPECT_EQ(objects[1].get<PDFObjectRef>()->gennum, 5); + + EXPECT_THROW(parser.parse("1 obj\n1 2 3 4 5endobj"), PDFException); + EXPECT_THROW(parser.parse("1 (string)obj\n1 2 3 4 5endobj"), PDFException); + + EXPECT_THROW(parser.parse("1 R"), PDFException); + EXPECT_THROW(parser.parse("1 (string)R"), PDFException); +} + + +TEST(PDFParserTest, stream) { + PDFParser parser; + vector<PDFObject> objects = parser.parse("stream\n1 2 3 4 endstream"); + ASSERT_EQ(objects.size(), 1u); + ASSERT_NE(objects[0].get<PDFStream>(), nullptr); +} + + +TEST(PDFParserTest, ops1) { + PDFParser parser; + vector<PDFObject> objects = parser.parse("@xpos 1op op2 1..2"); + ASSERT_EQ(objects.size(), 4u); + size_t count=0; + for (string str : {"@xpos", "1op", "op2", "1..2"}) { + ASSERT_NE(objects[count].get<PDFOperator>(), nullptr); + ASSERT_EQ(objects[count++].get<PDFOperator>()->opname, str); + } +} + + +TEST(PDFParserTest, ops2) { + PDFParser parser; + vector<PDFObject> objects = parser.parse("@xpos 1op op2 @ypos", [](const string &str, vector<PDFObject> &objects) { + if (str == "@xpos" || str == "@ypos") + objects.emplace_back(PDFObject(str == "@xpos" ? 1.23 : 3.21)); + else + objects.emplace_back(PDFOperator(str)); + }); + ASSERT_EQ(objects.size(), 4u); + size_t count=0; + for (string str : {"1.23", "1op", "op2", "3.21"}) { + ASSERT_EQ(string(objects[count++]), str); + } +} |