/** * @file test_bufferstream.hpp * @brief unit tests for the LLCore::BufferArrayStreamBuf/BufferArrayStream classes * * $LicenseInfo:firstyear=2012&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2012, Linden Research, Inc. * * This library 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; * version 2.1 of the License only. * * This library 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 library; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA * * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ #ifndef TEST_LLCORE_BUFFER_STREAM_H_ #define TEST_LLCORE_BUFFER_STREAM_H_ #include "bufferstream.h" #include #include "llsd.h" #include "llsdserialize.h" using namespace LLCore; namespace tut { struct BufferStreamTestData { // the test objects inherit from this so the member functions and variables // can be referenced directly inside of the test functions. }; typedef test_group BufferStreamTestGroupType; typedef BufferStreamTestGroupType::object BufferStreamTestObjectType; BufferStreamTestGroupType BufferStreamTestGroup("BufferStream Tests"); typedef BufferArrayStreamBuf::traits_type tst_traits_t; template <> template <> void BufferStreamTestObjectType::test<1>() { set_test_name("BufferArrayStreamBuf construction with NULL BufferArray"); // create a new ref counted object with an implicit reference BufferArrayStreamBuf * bsb = new BufferArrayStreamBuf(NULL); // Not much will work with a NULL ensure("underflow() on NULL fails", tst_traits_t::eof() == bsb->underflow()); ensure("uflow() on NULL fails", tst_traits_t::eof() == bsb->uflow()); ensure("pbackfail() on NULL fails", tst_traits_t::eof() == bsb->pbackfail('c')); ensure("showmanyc() on NULL fails", bsb->showmanyc() == -1); ensure("overflow() on NULL fails", tst_traits_t::eof() == bsb->overflow('c')); ensure("xsputn() on NULL fails", bsb->xsputn("blah", 4) == 0); ensure("seekoff() on NULL fails", bsb->seekoff(0, std::ios_base::beg, std::ios_base::in) == std::streampos(-1)); // release the implicit reference, causing the object to be released delete bsb; bsb = NULL; } template <> template <> void BufferStreamTestObjectType::test<2>() { set_test_name("BufferArrayStream construction with NULL BufferArray"); // create a new ref counted object with an implicit reference BufferArrayStream * bas = new BufferArrayStream(NULL); // Not much will work with a NULL here ensure("eof() is false on NULL", ! bas->eof()); ensure("fail() is false on NULL", ! bas->fail()); ensure("good() on NULL", bas->good()); // release the implicit reference, causing the object to be released delete bas; bas = NULL; } template <> template <> void BufferStreamTestObjectType::test<3>() { set_test_name("BufferArrayStreamBuf construction with empty BufferArray"); // create a new ref counted BufferArray with implicit reference BufferArray * ba = new BufferArray; BufferArrayStreamBuf * bsb = new BufferArrayStreamBuf(ba); // I can release my ref on the BA ba->release(); ba = NULL; // release the implicit reference, causing the object to be released delete bsb; bsb = NULL; } template <> template <> void BufferStreamTestObjectType::test<4>() { set_test_name("BufferArrayStream construction with empty BufferArray"); // create a new ref counted BufferArray with implicit reference BufferArray * ba = new BufferArray; { // create a new ref counted object with an implicit reference BufferArrayStream bas(ba); } // release the implicit reference, causing the object to be released ba->release(); ba = NULL; } template <> template <> void BufferStreamTestObjectType::test<5>() { set_test_name("BufferArrayStreamBuf construction with real BufferArray"); // create a new ref counted BufferArray with implicit reference BufferArray * ba = new BufferArray; const char * content("This is a string. A fragment."); const size_t c_len(strlen(content)); ba->append(content, c_len); // Creat an adapter for the BufferArray BufferArrayStreamBuf * bsb = new BufferArrayStreamBuf(ba); // I can release my ref on the BA ba->release(); ba = NULL; // Various static state ensure("underflow() returns 'T'", bsb->underflow() == 'T'); ensure("underflow() returns 'T' again", bsb->underflow() == 'T'); ensure("uflow() returns 'T'", bsb->uflow() == 'T'); ensure("uflow() returns 'h'", bsb->uflow() == 'h'); ensure("pbackfail('i') fails", tst_traits_t::eof() == bsb->pbackfail('i')); ensure("pbackfail('T') fails", tst_traits_t::eof() == bsb->pbackfail('T')); ensure("pbackfail('h') succeeds", bsb->pbackfail('h') == 'h'); ensure("showmanyc() is everything but the 'T'", bsb->showmanyc() == (c_len - 1)); ensure("overflow() appends", bsb->overflow('c') == 'c'); ensure("showmanyc() reflects append", bsb->showmanyc() == (c_len - 1 + 1)); ensure("xsputn() appends some more", bsb->xsputn("bla!", 4) == 4); ensure("showmanyc() reflects 2nd append", bsb->showmanyc() == (c_len - 1 + 5)); ensure("seekoff() succeeds", bsb->seekoff(0, std::ios_base::beg, std::ios_base::in) == std::streampos(0)); ensure("seekoff() succeeds 2", bsb->seekoff(4, std::ios_base::cur, std::ios_base::in) == std::streampos(4)); ensure("showmanyc() picks up seekoff", bsb->showmanyc() == (c_len + 5 - 4)); ensure("seekoff() succeeds 3", bsb->seekoff(0, std::ios_base::end, std::ios_base::in) == std::streampos(c_len + 4)); ensure("pbackfail('!') succeeds", tst_traits_t::eof() == bsb->pbackfail('!')); // release the implicit reference, causing the object to be released delete bsb; bsb = NULL; } template <> template <> void BufferStreamTestObjectType::test<6>() { set_test_name("BufferArrayStream construction with real BufferArray"); // create a new ref counted BufferArray with implicit reference BufferArray * ba = new BufferArray; //const char * content("This is a string. A fragment."); //const size_t c_len(strlen(content)); //ba->append(content, strlen(content)); { // Creat an adapter for the BufferArray BufferArrayStream bas(ba); // Basic operations bas << "Hello" << 27 << "."; ensure("BA length 8", ba->size() == 8); std::string str; bas >> str; ensure("reads correctly", str == "Hello27."); } // release the implicit reference, causing the object to be released ba->release(); ba = NULL; } template <> template <> void BufferStreamTestObjectType::test<7>() { set_test_name("BufferArrayStream with LLSD serialization"); // create a new ref counted BufferArray with implicit reference BufferArray * ba = new BufferArray; { // Creat an adapter for the BufferArray BufferArrayStream bas(ba); // LLSD LLSD llsd = LLSD::emptyMap(); llsd["int"] = LLSD::Integer(3); llsd["float"] = LLSD::Real(923289.28992); llsd["string"] = LLSD::String("aksjdl;ajsdgfjgfal;sdgjakl;sdfjkl;ajsdfkl;ajsdfkl;jaskl;dfj"); LLSD llsd_map = LLSD::emptyMap(); llsd_map["int"] = LLSD::Integer(-2889); llsd_map["float"] = LLSD::Real(2.37829e32); llsd_map["string"] = LLSD::String("OHIGODHSPDGHOSDHGOPSHDGP"); llsd["map"] = llsd_map; // Serialize it LLSDSerialize::toXML(llsd, bas); std::string str; bas >> str; // std::cout << "SERIALIZED LLSD: " << str << std::endl; ensure("Extracted string has reasonable length", str.size() > 60); } // release the implicit reference, causing the object to be released ba->release(); ba = NULL; } } // end namespace tut #endif // TEST_LLCORE_BUFFER_STREAM_H_