summaryrefslogtreecommitdiff
path: root/test/ValueBaseBencodeParserTest.cc
diff options
context:
space:
mode:
authorTatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>2012-07-24 23:50:06 +0900
committerTatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>2012-07-24 23:50:06 +0900
commit8311d6ef871285a8252740d3193221197af016dc (patch)
treea86a8a4dd99794a2120e860a6609ae741e666a7b /test/ValueBaseBencodeParserTest.cc
parent9620bb0a6d399ba04f89f575f98eb53b3b252020 (diff)
Added stream Bencode parser
Diffstat (limited to 'test/ValueBaseBencodeParserTest.cc')
-rw-r--r--test/ValueBaseBencodeParserTest.cc200
1 files changed, 200 insertions, 0 deletions
diff --git a/test/ValueBaseBencodeParserTest.cc b/test/ValueBaseBencodeParserTest.cc
new file mode 100644
index 00000000..677f1dce
--- /dev/null
+++ b/test/ValueBaseBencodeParserTest.cc
@@ -0,0 +1,200 @@
+#include "ValueBaseBencodeParser.h"
+
+#include <cppunit/extensions/HelperMacros.h>
+
+#include "ValueBase.h"
+
+namespace aria2 {
+
+class ValueBaseBencodeParserTest:public CppUnit::TestFixture {
+
+ CPPUNIT_TEST_SUITE(ValueBaseBencodeParserTest);
+ CPPUNIT_TEST(testParseUpdate);
+ CPPUNIT_TEST_SUITE_END();
+public:
+ void testParseUpdate();
+};
+
+CPPUNIT_TEST_SUITE_REGISTRATION( ValueBaseBencodeParserTest );
+
+namespace {
+void checkDecodeError(const std::string& src)
+{
+ bittorrent::ValueBaseBencodeParser parser;
+ ssize_t error;
+ SharedHandle<ValueBase> r = parser.parseFinal(src.c_str(), src.size(),
+ error);
+ CPPUNIT_ASSERT(!r);
+ CPPUNIT_ASSERT(error < 0);
+}
+} // namespace
+
+void ValueBaseBencodeParserTest::testParseUpdate()
+{
+ bittorrent::ValueBaseBencodeParser parser;
+ ssize_t error;
+ {
+ // empty string
+ std::string src = "0:";
+ SharedHandle<ValueBase> s = parser.parseFinal(src.c_str(), src.size(),
+ error);
+ CPPUNIT_ASSERT_EQUAL(std::string(""), downcast<String>(s)->s());
+ }
+ {
+ // integer 0
+ std::string src = "i0e";
+ SharedHandle<ValueBase> s = parser.parseFinal(src.c_str(), src.size(),
+ error);
+ CPPUNIT_ASSERT_EQUAL((int64_t)0, downcast<Integer>(s)->i());
+ }
+ {
+ // empty dict
+ std::string src = "de";
+ SharedHandle<ValueBase> d = parser.parseFinal(src.c_str(), src.size(),
+ error);
+ CPPUNIT_ASSERT(downcast<Dict>(d)->empty());
+ }
+ {
+ // empty list
+ std::string src = "le";
+ SharedHandle<ValueBase> l = parser.parseFinal(src.c_str(), src.size(),
+ error);
+ CPPUNIT_ASSERT(downcast<List>(l)->empty());
+ }
+ {
+ // string
+ std::string src = "3:foo";
+ SharedHandle<ValueBase> s = parser.parseFinal(src.c_str(), src.size(),
+ error);
+ CPPUNIT_ASSERT_EQUAL(std::string("foo"), downcast<String>(s)->s());
+ }
+ {
+ // integer
+ std::string src = "i9223372036854775807e";
+ SharedHandle<ValueBase> s = parser.parseFinal(src.c_str(), src.size(),
+ error);
+ CPPUNIT_ASSERT_EQUAL((int64_t)9223372036854775807LL,
+ downcast<Integer>(s)->i());
+ }
+ {
+ // dict, size 1
+ std::string src = "d3:fooi123ee";
+ SharedHandle<ValueBase> d = parser.parseFinal(src.c_str(), src.size(),
+ error);
+ Dict* dict = downcast<Dict>(d);
+ CPPUNIT_ASSERT(dict);
+ CPPUNIT_ASSERT(dict->get("foo"));
+ CPPUNIT_ASSERT_EQUAL((int64_t)123,
+ downcast<Integer>(dict->get("foo"))->i());
+ }
+ {
+ // dict, size 2
+ std::string src = "d3:fooi123e3:bar1:ee";
+ SharedHandle<ValueBase> d = parser.parseFinal(src.c_str(), src.size(),
+ error);
+ Dict* dict = downcast<Dict>(d);
+ CPPUNIT_ASSERT(dict);
+ CPPUNIT_ASSERT_EQUAL((size_t)2, dict->size());
+ CPPUNIT_ASSERT(dict->get("foo"));
+ CPPUNIT_ASSERT_EQUAL((int64_t)123,
+ downcast<Integer>(dict->get("foo"))->i());
+ CPPUNIT_ASSERT(dict->get("bar"));
+ CPPUNIT_ASSERT_EQUAL(std::string("e"),
+ downcast<String>(dict->get("bar"))->s());
+ }
+ {
+ // list, size 1
+ std::string src = "l3:fooe";
+ SharedHandle<ValueBase> l = parser.parseFinal(src.c_str(), src.size(),
+ error);
+ List* list = downcast<List>(l);
+ CPPUNIT_ASSERT(list);
+ CPPUNIT_ASSERT_EQUAL((size_t)1, list->size());
+ CPPUNIT_ASSERT_EQUAL(std::string("foo"),
+ downcast<String>(list->get(0))->s());
+ }
+ {
+ // list, size 2
+ std::string src = "l3:fooi123ee";
+ SharedHandle<ValueBase> l = parser.parseFinal(src.c_str(), src.size(),
+ error);
+ List* list = downcast<List>(l);
+ CPPUNIT_ASSERT(list);
+ CPPUNIT_ASSERT_EQUAL((size_t)2, list->size());
+ CPPUNIT_ASSERT_EQUAL(std::string("foo"),
+ downcast<String>(list->get(0))->s());
+ CPPUNIT_ASSERT_EQUAL((int64_t)123,
+ downcast<Integer>(list->get(1))->i());
+ }
+ {
+ // string, integer and list in dict
+ std::string src = "d4:name5:aria24:sizei12345678900e5:filesl3:bin3:docee";
+ SharedHandle<ValueBase> r = parser.parseFinal(src.c_str(), src.size(),
+ error);
+ const Dict* dict = downcast<Dict>(r);
+ CPPUNIT_ASSERT(dict);
+ CPPUNIT_ASSERT_EQUAL(std::string("aria2"),
+ downcast<String>(dict->get("name"))->s());
+ CPPUNIT_ASSERT_EQUAL(static_cast<Integer::ValueType>(12345678900LL),
+ downcast<Integer>(dict->get("size"))->i());
+ const List* list = downcast<List>(dict->get("files"));
+ CPPUNIT_ASSERT(list);
+ CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(2), list->size());
+ CPPUNIT_ASSERT_EQUAL(std::string("bin"),
+ downcast<String>(list->get(0))->s());
+ CPPUNIT_ASSERT_EQUAL(std::string("doc"),
+ downcast<String>(list->get(1))->s());
+ }
+ {
+ // dict in list
+ std::string src = "ld1:ki123eee";
+ SharedHandle<ValueBase> r = parser.parseFinal(src.c_str(), src.size(),
+ error);
+ const List* list = downcast<List>(r);
+ CPPUNIT_ASSERT(list);
+ CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), list->size());
+ const Dict* dict = downcast<Dict>(list->get(0));
+ CPPUNIT_ASSERT(dict);
+ CPPUNIT_ASSERT_EQUAL(static_cast<Integer::ValueType>(123),
+ downcast<Integer>(dict->get("k"))->i());
+ }
+ {
+ // empty key is allowed
+ std::string src = "d0:1:ve";
+ SharedHandle<ValueBase> s = parser.parseFinal(src.c_str(), src.size(),
+ error);
+ }
+ {
+ // empty encoded data
+ std::string src = "";
+ SharedHandle<ValueBase> s = parser.parseFinal(src.c_str(), src.size(),
+ error);
+ CPPUNIT_ASSERT(!s);
+ }
+ // integer, without ending 'e'
+ checkDecodeError("i3");
+ // dict, without ending 'e'
+ checkDecodeError("d");
+ // list, without ending 'e'
+ checkDecodeError("l");
+ // string, less than the specified length.
+ checkDecodeError("3:ab");
+ // string, but length is invalid
+ checkDecodeError("x:abc");
+ // string with minus length
+ checkDecodeError("-1:a");
+ // too deep structure
+ checkDecodeError(std::string(51, 'l')+std::string(51,'e'));
+ checkDecodeError(std::string(50, 'l')+"d3:fooi100ee"+std::string(50,'e'));
+ {
+ // ignore trailing garbage at the end of the input.
+ std::string src = "5:aria2trail";
+ SharedHandle<ValueBase> s = parser.parseFinal(src.c_str(), src.size(),
+ error);
+ CPPUNIT_ASSERT_EQUAL(std::string("aria2"), downcast<String>(s)->s());
+ // Get trailing garbage position
+ CPPUNIT_ASSERT_EQUAL((ssize_t)7, error);
+ }
+}
+
+} // namespace aria2