Moved to CppUnit for unit tests framework.

This commit is contained in:
Vincent Richard 2005-08-25 21:25:45 +00:00
parent 7ac14499f0
commit 5d18fce959
51 changed files with 2748 additions and 9593 deletions

View File

@ -2,6 +2,10 @@
VERSION 0.7.2cvs VERSION 0.7.2cvs
================ ================
2005-08-25 Vincent Richard <vincent@vincent-richard.net>
* Tests: moved to CppUnit for unit tests framework.
2005-08-23 Vincent Richard <vincent@vincent-richard.net> 2005-08-23 Vincent Richard <vincent@vincent-richard.net>
* All sources: renamed 'vmime::messaging' to 'vmime::net'. An alias has been * All sources: renamed 'vmime::messaging' to 'vmime::net'. An alias has been

View File

@ -290,66 +290,31 @@ libvmime_tests = [
'tests/charset/test-suites/gnu.out.iso-8859-1', 'tests/charset/test-suites/gnu.out.iso-8859-1',
] ]
libunitpp_common = [
'tests/lib/unit++/aclocal.m4',
'tests/lib/unit++/COPYING',
'tests/lib/unit++/guitester.cc',
'tests/lib/unit++/main.h',
'tests/lib/unit++/optmap-compat.h',
'tests/lib/unit++/tester.h',
'tests/lib/unit++/Test_unit++.cc',
'tests/lib/unit++/unit++-compat.h',
'tests/lib/unit++/Changelog',
'tests/lib/unit++/guitester.h',
'tests/lib/unit++/optmap.h',
'tests/lib/unit++/unit++.1',
'tests/lib/unit++/unit++.h',
'tests/lib/unit++/gui.cc',
'tests/lib/unit++/INSTALL',
# 'tests/lib/unit++/Makefile.in',
'tests/lib/unit++/Test_gui.cc',
'tests/lib/unit++/unit++.3',
'tests/lib/unit++/configure.ac',
'tests/lib/unit++/gui.h',
# 'tests/lib/unit++/main.cc',
# 'tests/lib/unit++/optmap.cc',
# 'tests/lib/unit++/tester.cc',
'tests/lib/unit++/Test_optmap.cc',
# 'tests/lib/unit++/unit++.cc',
'tests/lib/unit++/unitpp.m4'
]
libunitpp_sources = [
'tests/lib/unit++/unit++.cc',
'tests/lib/unit++/main.cc',
'tests/lib/unit++/optmap.cc',
'tests/lib/unit++/tester.cc'
]
libvmimetest_common = [ libvmimetest_common = [
'tests/parser/testUtils.hpp' 'tests/testUtils.hpp'
] ]
libvmimetest_sources = [ libvmimetest_sources = [
[ 'tests/parser/bodyPartTest', [ 'tests/parser/bodyPartTest.cpp' ] ], 'tests/testRunner.cpp',
[ 'tests/parser/datetimeTest', [ 'tests/parser/datetimeTest.cpp' ] ], 'tests/parser/bodyPartTest.cpp',
[ 'tests/parser/dispositionTest', [ 'tests/parser/dispositionTest.cpp' ] ], 'tests/parser/datetimeTest.cpp',
[ 'tests/parser/encoderTest', [ 'tests/parser/encoderTest.cpp' ] ], 'tests/parser/dispositionTest.cpp',
[ 'tests/parser/headerTest', [ 'tests/parser/headerTest.cpp' ] ], 'tests/parser/encoderTest.cpp',
[ 'tests/parser/mailboxTest', [ 'tests/parser/mailboxTest.cpp' ] ], 'tests/parser/headerTest.cpp',
[ 'tests/parser/mediaTypeTest', [ 'tests/parser/mediaTypeTest.cpp' ] ], 'tests/parser/mailboxTest.cpp',
[ 'tests/parser/messageIdTest', [ 'tests/parser/messageIdTest.cpp' ] ], 'tests/parser/mediaTypeTest.cpp',
[ 'tests/parser/messageIdSequenceTest', [ 'tests/parser/messageIdSequenceTest.cpp' ] ], 'tests/parser/messageIdTest.cpp',
[ 'tests/parser/pathTest', [ 'tests/parser/pathTest.cpp' ] ], 'tests/parser/messageIdSequenceTest.cpp',
[ 'tests/parser/parameterTest', [ 'tests/parser/parameterTest.cpp' ] ], 'tests/parser/pathTest.cpp',
[ 'tests/parser/textTest', [ 'tests/parser/textTest.cpp' ] ], 'tests/parser/parameterTest.cpp',
[ 'tests/utility/filteredStreamTest', [ 'tests/utility/filteredStreamTest.cpp' ] ], 'tests/parser/textTest.cpp',
[ 'tests/utility/md5Test', [ 'tests/utility/md5Test.cpp' ] ], 'tests/utility/filteredStreamTest.cpp',
[ 'tests/utility/stringProxyTest', [ 'tests/utility/stringProxyTest.cpp' ] ], 'tests/utility/md5Test.cpp',
[ 'tests/utility/stringUtilsTest', [ 'tests/utility/stringUtilsTest.cpp' ] ], 'tests/utility/stringProxyTest.cpp',
[ 'tests/utility/pathTest', [ 'tests/utility/pathTest.cpp' ] ], 'tests/utility/stringUtilsTest.cpp',
[ 'tests/utility/urlTest', [ 'tests/utility/urlTest.cpp' ] ], 'tests/utility/pathTest.cpp',
[ 'tests/utility/smartPtrTest', [ 'tests/utility/smartPtrTest.cpp' ] ] 'tests/utility/urlTest.cpp',
'tests/utility/smartPtrTest.cpp'
] ]
libvmime_autotools = [ libvmime_autotools = [
@ -398,15 +363,10 @@ for p in libvmime_platforms_sources:
libvmime_dist_files = libvmime_all_sources + libvmime_extra + libvmime_examples_sources libvmime_dist_files = libvmime_all_sources + libvmime_extra + libvmime_examples_sources
libvmime_dist_files += libvmime_tests libvmime_dist_files += libvmime_tests
libvmime_dist_files += libunitpp_common libvmime_dist_files += libvmimetest_sources
libvmime_dist_files += libunitpp_sources
libvmime_dist_files += libvmimetest_common libvmime_dist_files += libvmimetest_common
libvmime_dist_files += libvmime_autotools libvmime_dist_files += libvmime_autotools
for t in libvmimetest_sources:
for f in t[1]:
libvmime_dist_files.append(f)
################# #################
# Set options # # Set options #
@ -530,7 +490,7 @@ opts.AddOptions(
), ),
EnumOption( EnumOption(
'build_tests', 'build_tests',
'Build unit tests (in "tests" directory)', 'Build unit tests (run with "scons run-tests")',
'no', 'no',
allowed_values = ('yes', 'no'), allowed_values = ('yes', 'no'),
map = { }, map = { },
@ -872,22 +832,14 @@ Default(libVmime)
# Tests # Tests
if env['build_tests'] == 'yes': if env['build_tests'] == 'yes':
if env['debug'] == 'yes': if env['debug'] == 'yes':
libUnitpp = env.StaticLibrary( Default(
target = 'tests/unit++', env.Program(
source = libunitpp_sources target = 'run-tests',
) source = libvmimetest_sources,
LIBS=['cppunit', 'dl', packageVersionedGenericName + '-debug'],
Default(libUnitpp) LIBPATH=['.']
for test in libvmimetest_sources:
Default(
env.Program(
target = test[0],
source = test[1],
LIBS=['unit++', packageVersionedGenericName + '-debug'],
LIBPATH=['.', './tests/']
)
) )
)
else: else:
print 'Debug mode must be enabled to build tests!' print 'Debug mode must be enabled to build tests!'
Exit(1) Exit(1)
@ -2101,11 +2053,7 @@ env.Alias('doc', doxygenDocPath)
################ ################
def runTests(target, source, env): def runTests(target, source, env):
for t in libvmimetest_sources: os.system("./run-tests")
print ""
print t[0] + ':' # test name
os.system(t[0])
return None return None

View File

@ -1,359 +0,0 @@
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 2 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,
write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA.
The author can be contacted at azhrarn@users.sourceforge.net.
GNU GENERAL PUBLIC LICENSE
Version 2, June 1991
Copyright (C) 1989, 1991 Free Software Foundation, Inc.
59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
Preamble
The licenses for most software are designed to take away your
freedom to share and change it. By contrast, the GNU General Public
License is intended to guarantee your freedom to share and change free
software--to make sure the software is free for all its users. This
General Public License applies to most of the Free Software
Foundation's software and to any other program whose authors commit to
using it. (Some other Free Software Foundation software is covered by
the GNU Library General Public License instead.) You can apply it to
your programs, too.
When we speak of free software, we are referring to freedom, not
price. Our General Public Licenses are designed to make sure that you
have the freedom to distribute copies of free software (and charge for
this service if you wish), that you receive source code or can get it
if you want it, that you can change the software or use pieces of it
in new free programs; and that you know you can do these things.
To protect your rights, we need to make restrictions that forbid
anyone to deny you these rights or to ask you to surrender the rights.
These restrictions translate to certain responsibilities for you if you
distribute copies of the software, or if you modify it.
For example, if you distribute copies of such a program, whether
gratis or for a fee, you must give the recipients all the rights that
you have. You must make sure that they, too, receive or can get the
source code. And you must show them these terms so they know their
rights.
We protect your rights with two steps: (1) copyright the software, and
(2) offer you this license which gives you legal permission to copy,
distribute and/or modify the software.
Also, for each author's protection and ours, we want to make certain
that everyone understands that there is no warranty for this free
software. If the software is modified by someone else and passed on, we
want its recipients to know that what they have is not the original, so
that any problems introduced by others will not reflect on the original
authors' reputations.
Finally, any free program is threatened constantly by software
patents. We wish to avoid the danger that redistributors of a free
program will individually obtain patent licenses, in effect making the
program proprietary. To prevent this, we have made it clear that any
patent must be licensed for everyone's free use or not licensed at all.
The precise terms and conditions for copying, distribution and
modification follow.
GNU GENERAL PUBLIC LICENSE
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
0. This License applies to any program or other work which contains
a notice placed by the copyright holder saying it may be distributed
under the terms of this General Public License. The "Program", below,
refers to any such program or work, and a "work based on the Program"
means either the Program or any derivative work under copyright law:
that is to say, a work containing the Program or a portion of it,
either verbatim or with modifications and/or translated into another
language. (Hereinafter, translation is included without limitation in
the term "modification".) Each licensee is addressed as "you".
Activities other than copying, distribution and modification are not
covered by this License; they are outside its scope. The act of
running the Program is not restricted, and the output from the Program
is covered only if its contents constitute a work based on the
Program (independent of having been made by running the Program).
Whether that is true depends on what the Program does.
1. You may copy and distribute verbatim copies of the Program's
source code as you receive it, in any medium, provided that you
conspicuously and appropriately publish on each copy an appropriate
copyright notice and disclaimer of warranty; keep intact all the
notices that refer to this License and to the absence of any warranty;
and give any other recipients of the Program a copy of this License
along with the Program.
You may charge a fee for the physical act of transferring a copy, and
you may at your option offer warranty protection in exchange for a fee.
2. You may modify your copy or copies of the Program or any portion
of it, thus forming a work based on the Program, and copy and
distribute such modifications or work under the terms of Section 1
above, provided that you also meet all of these conditions:
a) You must cause the modified files to carry prominent notices
stating that you changed the files and the date of any change.
b) You must cause any work that you distribute or publish, that in
whole or in part contains or is derived from the Program or any
part thereof, to be licensed as a whole at no charge to all third
parties under the terms of this License.
c) If the modified program normally reads commands interactively
when run, you must cause it, when started running for such
interactive use in the most ordinary way, to print or display an
announcement including an appropriate copyright notice and a
notice that there is no warranty (or else, saying that you provide
a warranty) and that users may redistribute the program under
these conditions, and telling the user how to view a copy of this
License. (Exception: if the Program itself is interactive but
does not normally print such an announcement, your work based on
the Program is not required to print an announcement.)
These requirements apply to the modified work as a whole. If
identifiable sections of that work are not derived from the Program,
and can be reasonably considered independent and separate works in
themselves, then this License, and its terms, do not apply to those
sections when you distribute them as separate works. But when you
distribute the same sections as part of a whole which is a work based
on the Program, the distribution of the whole must be on the terms of
this License, whose permissions for other licensees extend to the
entire whole, and thus to each and every part regardless of who wrote it.
Thus, it is not the intent of this section to claim rights or contest
your rights to work written entirely by you; rather, the intent is to
exercise the right to control the distribution of derivative or
collective works based on the Program.
In addition, mere aggregation of another work not based on the Program
with the Program (or with a work based on the Program) on a volume of
a storage or distribution medium does not bring the other work under
the scope of this License.
3. You may copy and distribute the Program (or a work based on it,
under Section 2) in object code or executable form under the terms of
Sections 1 and 2 above provided that you also do one of the following:
a) Accompany it with the complete corresponding machine-readable
source code, which must be distributed under the terms of Sections
1 and 2 above on a medium customarily used for software interchange; or,
b) Accompany it with a written offer, valid for at least three
years, to give any third party, for a charge no more than your
cost of physically performing source distribution, a complete
machine-readable copy of the corresponding source code, to be
distributed under the terms of Sections 1 and 2 above on a medium
customarily used for software interchange; or,
c) Accompany it with the information you received as to the offer
to distribute corresponding source code. (This alternative is
allowed only for noncommercial distribution and only if you
received the program in object code or executable form with such
an offer, in accord with Subsection b above.)
The source code for a work means the preferred form of the work for
making modifications to it. For an executable work, complete source
code means all the source code for all modules it contains, plus any
associated interface definition files, plus the scripts used to
control compilation and installation of the executable. However, as a
special exception, the source code distributed need not include
anything that is normally distributed (in either source or binary
form) with the major components (compiler, kernel, and so on) of the
operating system on which the executable runs, unless that component
itself accompanies the executable.
If distribution of executable or object code is made by offering
access to copy from a designated place, then offering equivalent
access to copy the source code from the same place counts as
distribution of the source code, even though third parties are not
compelled to copy the source along with the object code.
4. You may not copy, modify, sublicense, or distribute the Program
except as expressly provided under this License. Any attempt
otherwise to copy, modify, sublicense or distribute the Program is
void, and will automatically terminate your rights under this License.
However, parties who have received copies, or rights, from you under
this License will not have their licenses terminated so long as such
parties remain in full compliance.
5. You are not required to accept this License, since you have not
signed it. However, nothing else grants you permission to modify or
distribute the Program or its derivative works. These actions are
prohibited by law if you do not accept this License. Therefore, by
modifying or distributing the Program (or any work based on the
Program), you indicate your acceptance of this License to do so, and
all its terms and conditions for copying, distributing or modifying
the Program or works based on it.
6. Each time you redistribute the Program (or any work based on the
Program), the recipient automatically receives a license from the
original licensor to copy, distribute or modify the Program subject to
these terms and conditions. You may not impose any further
restrictions on the recipients' exercise of the rights granted herein.
You are not responsible for enforcing compliance by third parties to
this License.
7. If, as a consequence of a court judgment or allegation of patent
infringement or for any other reason (not limited to patent issues),
conditions are imposed on you (whether by court order, agreement or
otherwise) that contradict the conditions of this License, they do not
excuse you from the conditions of this License. If you cannot
distribute so as to satisfy simultaneously your obligations under this
License and any other pertinent obligations, then as a consequence you
may not distribute the Program at all. For example, if a patent
license would not permit royalty-free redistribution of the Program by
all those who receive copies directly or indirectly through you, then
the only way you could satisfy both it and this License would be to
refrain entirely from distribution of the Program.
If any portion of this section is held invalid or unenforceable under
any particular circumstance, the balance of the section is intended to
apply and the section as a whole is intended to apply in other
circumstances.
It is not the purpose of this section to induce you to infringe any
patents or other property right claims or to contest validity of any
such claims; this section has the sole purpose of protecting the
integrity of the free software distribution system, which is
implemented by public license practices. Many people have made
generous contributions to the wide range of software distributed
through that system in reliance on consistent application of that
system; it is up to the author/donor to decide if he or she is willing
to distribute software through any other system and a licensee cannot
impose that choice.
This section is intended to make thoroughly clear what is believed to
be a consequence of the rest of this License.
8. If the distribution and/or use of the Program is restricted in
certain countries either by patents or by copyrighted interfaces, the
original copyright holder who places the Program under this License
may add an explicit geographical distribution limitation excluding
those countries, so that distribution is permitted only in or among
countries not thus excluded. In such case, this License incorporates
the limitation as if written in the body of this License.
9. The Free Software Foundation may publish revised and/or new versions
of the General Public License from time to time. Such new versions will
be similar in spirit to the present version, but may differ in detail to
address new problems or concerns.
Each version is given a distinguishing version number. If the Program
specifies a version number of this License which applies to it and "any
later version", you have the option of following the terms and conditions
either of that version or of any later version published by the Free
Software Foundation. If the Program does not specify a version number of
this License, you may choose any version ever published by the Free Software
Foundation.
10. If you wish to incorporate parts of the Program into other free
programs whose distribution conditions are different, write to the author
to ask for permission. For software which is copyrighted by the Free
Software Foundation, write to the Free Software Foundation; we sometimes
make exceptions for this. Our decision will be guided by the two goals
of preserving the free status of all derivatives of our free software and
of promoting the sharing and reuse of software generally.
NO WARRANTY
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
REPAIR OR CORRECTION.
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
POSSIBILITY OF SUCH DAMAGES.
END OF TERMS AND CONDITIONS
How to Apply These Terms to Your New Programs
If you develop a new program, and you want it to be of the greatest
possible use to the public, the best way to achieve this is to make it
free software which everyone can redistribute and change under these terms.
To do so, attach the following notices to the program. It is safest
to attach them to the start of each source file to most effectively
convey the exclusion of warranty; and each file should have at least
the "copyright" line and a pointer to where the full notice is found.
<one line to give the program's name and a brief idea of what it does.>
Copyright (C) <year> <name of author>
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 2 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, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
Also add information on how to contact you by electronic and paper mail.
If the program is interactive, make it output a short notice like this
when it starts in an interactive mode:
Gnomovision version 69, Copyright (C) year name of author
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type `show c' for details.
The hypothetical commands `show w' and `show c' should show the appropriate
parts of the General Public License. Of course, the commands you use may
be called something other than `show w' and `show c'; they could even be
mouse-clicks or menu items--whatever suits your program.
You should also get your employer (if you work as a programmer) or your
school, if any, to sign a "copyright disclaimer" for the program, if
necessary. Here is a sample; alter the names:
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
`Gnomovision' (which makes passes at compilers) written by James Hacker.
<signature of Ty Coon>, 1 April 1989
Ty Coon, President of Vice
This General Public License does not permit incorporating your program into
proprietary programs. If your program is a subroutine library, you may
consider it more useful to permit linking proprietary applications with the
library. If this is what you want to do, use the GNU Library General
Public License instead of this License.

View File

@ -1,16 +0,0 @@
1.2:
Added a couple of man pages.
Incorporated some changes from Craig McGeachie to allow compilation on
MicroSoft Visual Studio.
Added a Qt GUI
Added Kenn Knowles' m4 automake configuration file for determining in an
automake file if unit++ is available
Added some typename hints for compilers less large than g++ (thanks to Doug
Philips). Should get it to compile on AIX 4.3.3.
1.1.1:
Before this list started...

View File

@ -1,59 +0,0 @@
The unit++ framework is meant to be very simple.
To install it:
./configure
make install
This should take care of everything, and install in
/usr/local/{lib,include,man}.
The all target (make all) will make the test for the test framework, unit++.
Try to run it to see that everything is fine. If you want to see a failing
test case, try `unit++ -f'.
Graphics
--------
My experience from junit are that a really great day ends with my test suite
producing that green bar... To gain that joy in C++ I have made a GUI for
unit++ based on Qt. However, it does take longer to run the unGUI version, and
I have therefore taken great care that this will still work without it.
The install instructions for the GUI version is:
./configure --with-qt
make install
This will enable the gui, that is add the GUI classes to the unit++ library.
It still requires that the individual test programs enables the GUI. This is
done by adding the following lines to one of the test modules:
#include <unit++/unit++.h>
unitpp::gui_hook ghook;
This will enable the -g (or --gui) option in the resulting executable.
NOTE:
=====
The tests don't work properly on old C++ compilers, without the <sstream>
header (stringstream classes). That includes the g++ 2.95.3 version found on
SunOS and OpenBSD. However, newer versions of libstd++3 works fine.
This means that some things will not be tested in this case, and some
spurious output will result from running the unit++ program. The final count
of tests is correct, even though the output strongly suggests otherwise.
====
Doc.
----
If you have doc++ available the API interface can be documented by `make
doc'. The DOCDIR variable in the Makefile controls where the files end up.
If you want the documentation without having doc++, I try to keep it update
on the SourceForge page: http://unitpp.sourceforge.net/docs/index.html.
It can be found as a file for download there as well.
Man pages
---------
I have added a man page for unit++(3). This documents the API to a level that
I deem sufficient for writing test cases.

View File

@ -1,80 +0,0 @@
# installation targets
prefix=@prefix@
includedir=@includedir@
exec_prefix=@exec_prefix@
libdir=@libdir@
mandir=@mandir@
docdir=./html/unit++
#various compilers.
CXX=@CXX@
CXXFLAGS=@CXXFLAGS@
# for those that have doc++, otherwise get it
DOC=doc++
#Qt related stuff
QT_LIBDIR = @QT_LDFLAGS@
QT_INCDIR = @QT_INCLUDES@
MOC = @MOC@
GUI_OBJS = @gui_vars@
GUI_DOCSRC = @gui_docsrc@
# Below here should not need modification
TARGETLIB=libunit++.a
TARGETHEADERS=unit++.h optmap.h gui.h guitester.h main.h tester.h
# substituted into GUI_OBJS by autoconf, if GUI is enabled
gui_objs = gui.o guitester.o moc_gui.o moc_guitester.o
gui_docsrc = gui.h guitester.h
OBJS=unit++.o tester.o main.o optmap.o $(GUI_OBJS)
#the files with doc information
DOCSRC=$(TARGETHEADERS) main.h tester.h $(GUI_DOCSRC)
DOCOPTS=-d $(docdir)
TSTOBJS=Test_unit++.o Test_optmap.o Test_gui.o
TSTLIBS=-L. -lunit++
.SUFFIXES: .cc
.cc.o:
$(CXX) -D__UNITPP -c $(CXXFLAGS) $(CPPFLAGS) @QT_INCLUDES@ @DEFS@ -o $@ $<
all: $(TARGETLIB) unit++
$(TARGETLIB): $(OBJS)
ar r $@ $(OBJS)
install: $(TARGETLIB) $(TARGETHEADERS)
[ -d $(libdir) ] || mkdir -p $(libdir)
[ -d $(includedir)/unit++ ] || mkdir -p $(includedir)/unit++
[ -d $(mandir)/man1 ] || mkdir -p $(mandir)/man1
[ -d $(mandir)/man3 ] || mkdir -p $(mandir)/man3
cp $(TARGETLIB) $(libdir)
cp $(TARGETHEADERS) $(includedir)/unit++
cp unit++-compat.h $(includedir)/unit++.h
cp optmap-compat.h $(includedir)/optmap.h
cp unit++.1 $(mandir)/man1
cp unit++.3 $(mandir)/man3
doc: $(DOCSRC)
[ -d $(docdir) ] || mkdir -p $(docdir)
doc++ $(DOCOPTS) $(DOCSRC)
unit++: $(TSTOBJS) $(TARGETLIB)
$(CXX) -o $@ $(TSTOBJS) $(TSTLIBS) @QT_LDFLAGS@ @qt_lib@
moc_gui.cc: gui.h
$(MOC) $< -o $@
moc_guitester.cc: guitester.h
$(MOC) $< -o $@
clean:
rm -f $(OBJS) $(TSTOBJS)
clobber: clean
rm -f $(TARGETLIB) unit++
Test_optmap.o: Test_optmap.cc unit++.h optmap.h
Test_unit++.o: Test_unit++.cc unit++.h optmap.h tester.h main.h
Test_gui.o: Test_gui.cc
gui.o: gui.cc gui.h unit++.h optmap.h
guitester.o: guitester.cc
main.o: main.cc main.h tester.h unit++.h optmap.h
optmap.o: optmap.cc optmap.h
tester.o: tester.cc tester.h unit++.h optmap.h
unit++.o: unit++.cc unit++.h optmap.h

View File

@ -1,27 +0,0 @@
// Copyright (C) 2001 Claus Dræby
// Terms of use are in the file COPYING
#ifdef GUI
#include "gui.h"
#include "unit++.h"
using namespace std;
using namespace unitpp;
gui_hook ghook; // ensure linkage of the gui stuff
namespace {
// The test suite for the gui components
class Test : public suite
{
void dummy()
{
}
public:
Test() : suite("GUI test suite")
{
suite::main().add("gui", this);
add("dummy", testcase(this, "Test nothing", &Test::dummy));
}
} * theTest = new Test();
}
#endif

View File

@ -1,101 +0,0 @@
// Copyright (C) 2001 Claus Dræby
// Terms of use are in the file COPYING
#include "unit++.h"
#include "optmap.h"
#include <iostream>
#ifdef HAVE_SSTREAM
#include <sstream>
#endif
using namespace std;
using namespace unitpp;
using namespace options_utils;
namespace {
const char* x[] = { "testing", "-i", "120", "-n100", "-t" };
#ifdef HAVE_SSTREAM
class hijack {
ostream& os;
streambuf* sbp;
stringbuf sb;
public:
hijack(ostream& os)
: os(os), sbp(os.rdbuf())
{
os.rdbuf(&sb);
}
~hijack() { os.rdbuf(sbp); }
string str() { return sb.str(); }
};
#endif
// The test suite for the optmap library
class Test : public suite
{
const char** argv;
int argc;
void create()
{
optmap om;
}
void usage()
{
bool t_flg;
int i = 7;
int n = 0;
optmap om;
om.add("t", new opt_flag(t_flg));
om.add("i", new opt_int(i));
om.add("n", new opt_int(n));
om.alias("number", "n");
#ifdef HAVE_SSTREAM
string exp(
"usage: testing [ -t ] [ -i <int> ] [( -n | --number) <int> ]\n");
{
hijack s(cerr);
om.parse(argc, argv);
om.usage(false);
assert_eq("usage", exp, s.str());
}
#endif
}
void args()
{
bool t_flg = false;
int i = 7;
int n = 0;
optmap om;
om.add("t", new opt_flag(t_flg));
om.add("i", new opt_int(i));
om.add("n", new opt_int(n));
assert_true("parse ok", om.parse(argc, argv));
assert_eq("get -i", 120, i);
assert_eq("get -n", 100, n);
assert_eq("got -t", true, t_flg);
}
void tail()
{
const char* argv[] = { "xyzzy", "-abc", "-def", "hij" };
size_t argc = sizeof(argv)/sizeof(argv[0]);
string s;
bool f_d, f_e, f_f;
optmap om;
om.add("a", new opt_string(s));
om.add("d", new opt_flag(f_d));
om.add("e", new opt_flag(f_e));
om.add("f", new opt_flag(f_f));
assert_true("parse", om.parse(static_cast<int>(argc), argv));
assert_eq("n", argc - 1, size_t(om.n()));
assert_eq("a", "bc", s);
}
public:
Test() : suite("optmap test suite")
{
argv = x;
argc = sizeof(x)/sizeof(char*);
suite::main().add("optmap", this);
add("create", testcase(this, "Create an optmap", &Test::create));
add("usage", testcase(this, "Optmap usage", &Test::usage));
add("args", testcase(this, "Optmap args", &Test::args));
add("tail", testcase(this, "Optmap tail", &Test::tail));
}
} * theTest = new Test();
}

View File

@ -1,194 +0,0 @@
// Copyright (C) 2001 Claus Dræby
// Terms of use are in the file COPYING
#include "unit++.h"
#include "tester.h"
#include "main.h"
#ifdef HAVE_SSTREAM
#include <sstream>
#else
#include <iostream>
#endif
using namespace std;
using namespace unitpp;
namespace {
// a test case that can fail with any exception
class test_test : public test
{
public:
enum result { succes, fail, error, exotic };
test_test(string name, result res = succes) : test(name), res(res) {}
virtual void operator()()
{
switch (res) {
case succes: break;
case fail: ::fail("test_test");
case error: throw out_of_range("ranged");
case exotic: throw 4711;
}
}
private:
result res;
};
// The test suite for the unit++ library
class Test : public suite
{
void create()
{
test_test a_loc_test("local");
}
void assert_ok()
{
string s("ok");
assert_true("assert_true(true)", true);
assert_eq("assert_eq(int)", 7, 7);
assert_eq("assert_eq(char*, string)", "ok", s);
}
void assert_fail()
{
string s("fejl");
bool ok = true;
try {
assert_true("assert_true(false)", false);
ok = false;
} catch (assertion_error e) {
#ifdef HAVE_SSTREAM
ostringstream oss;
oss << e;
assert_eq("assert_true(false) output",
"assert_true(false) [assertion failed]", oss.str());
#endif
}
if (!ok)
fail("no exception from assert_true(false)");
try {
assert_eq("assert_eq(int)", 5, 7);
ok = false;
} catch (assert_value_error<int,int> e) {
#ifdef HAVE_SSTREAM
ostringstream oss;
oss << e;
assert_eq("assert_eq(int) output",
"assert_eq(int) [expected: `5' got: `7']", oss.str());
#endif
}
if (!ok)
fail("no exception from assert_eq(int)");
try {
assert_eq("assert_eq(char*, string)", "ok", s);
ok = false;
} catch (assert_value_error<const char*, string> e) {
} catch (assert_value_error<char*, string> e) { // MSVC++ bug
}
if (!ok)
fail("no exception from assert_eq(const char*, string)");
}
void tester_visit()
{
out_of_range oor("negative");
assertion_error ae("test");
#ifdef HAVE_SSTREAM
ostringstream os;
tester tst(os);
#else
tester tst(cerr);
#endif
root.visit(&tst);
assert_eq("tests ok", 3, tst.res_tests().n_ok());
assert_eq("tests error", 2, tst.res_tests().n_err());
assert_eq("tests fail", 1, tst.res_tests().n_fail());
assert_eq("suites ok", 1, tst.res_suites().n_ok());
assert_eq("suites error", 2, tst.res_suites().n_err());
assert_eq("suites fail", 1, tst.res_suites().n_fail());
}
void ex_test()
{
throw out_of_range("expected");
}
void get_by_id()
{
test* p = root.get_child("s2");
assert_true("found s2", p != 0);
suite* sp = dynamic_cast<suite*>(p);
assert_true("s2 was suite", sp != 0);
assert_eq("right s2", "S2", sp->name());
p = sp->get_child("t20");
assert_true("found t20", p != 0);
assert_eq("not suite", static_cast<suite*>(0),dynamic_cast<suite*>(p));
}
void vec()
{
string s = "three.blind.mice";
vector<string> v(vectorize(s,'.'));
assert_eq("v[0]", string("three"), v[0]);
assert_eq("v[1]", string("blind"), v[1]);
assert_eq("v[2]", string("mice"), v[2]);
assert_eq("size", size_t(3), v.size());
v = vectorize(s,'-');
assert_eq("no match", s, v[0]);
assert_eq("no match size", size_t(1), v.size());
}
void empty_vec()
{
string s("");
vector<string> v(vectorize(s,'.'));
assert_eq("size", size_t(0), v.size());
s = "one..three";
v = vectorize(s,'.');
assert_eq("v[0]", string("one"), v[0]);
assert_eq("v[1]", string(""), v[1]);
assert_eq("v[2]", string("three"), v[2]);
assert_eq("size", size_t(3), v.size());
}
void find()
{
test* tp = root.find("s2.s21.t210");
assert_eq("t210", t210, tp);
tp = root.find("s1.s21");
assert_eq("bad mid", static_cast<test*>(0), tp);
}
suite root;
test* t210;
bool do_fail;
void fail_on_flag()
{
assert_true("Fail option not set", !do_fail);
}
public:
Test() : suite("Unit++ test suite"), root("The root")
{
do_fail = false;
options().add("f", new options_utils::opt_flag(do_fail));
options().alias("fail", "f");
suite* s1;
suite* s2;
suite* s21;
root.add("s1", s1 = new suite("S1"));
root.add("s2", s2 = new suite("S2"));
s2->add("s21", s21 = new suite("S21"));
s1->add("t10", new test_test("T10"));
s1->add("t11", new test_test("T11"));
s2->add("t20", new test_test("T20", test_test::error));
s2->add("t22", new test_test("T22", test_test::exotic));
s21->add("t210", t210 = new test_test("T210"));
s21->add("t211", new test_test("T211", test_test::fail));
//
// Adding testcases
suite::main().add("unitpp", this);
add("create", testcase(this, "Create a test", &Test::create));
add("assert_ok", testcase(this, "Assert ok", &Test::assert_ok));
add("assert_fail", testcase(this, "Assert fail", &Test::assert_fail));
add("tester_visit", testcase(this, "Visit", &Test::tester_visit));
add("exception", testcase(new exception_test<out_of_range>(
testcase(this, "gen ex", &Test::ex_test))));
add("id_get", testcase(this, "Get by id", &Test::get_by_id));
add("vec", testcase(this, "Vectorize", &Test::vec));
add("empty_vec", testcase(this, "Vectorize empty", &Test::empty_vec));
add("find", testcase(this, "find", &Test::find));
add("fail", testcase(this, "fail on option", &Test::fail_on_flag));
}
} * theTest = new Test();
}

View File

@ -1,314 +0,0 @@
dnl aclocal.m4 generated automatically by aclocal 1.4-p4
dnl Copyright (C) 1994, 1995-8, 1999 Free Software Foundation, Inc.
dnl This file is free software; the Free Software Foundation
dnl gives unlimited permission to copy and/or distribute it,
dnl with or without modifications, as long as this notice is preserved.
dnl This program is distributed in the hope that it will be useful,
dnl but WITHOUT ANY WARRANTY, to the extent permitted by law; without
dnl even the implied warranty of MERCHANTABILITY or FITNESS FOR A
dnl PARTICULAR PURPOSE.
dnl This file is part of QXi, the Qt XInput Extension.
dnl
dnl Copyright (C) 2000 Daniel Schmitt <pnambic@unu.nu>
dnl
dnl This file may be distributed under the terms of the Q Public License as
dnl appearing in the file COPYING.QPL included in the packaging of this file.
dnl
dnl The portions of this file that deal with the detection of Qt are
dnl stripped-down versions of macros used in KDE (http://www.kde.org/).
dnl
dnl The originals are copyrighted by
dnl Copyright (C) 1997 Janos Farkas (chexum@shadow.banki.hu)
dnl (C) 1997,98,99 Stephan Kulow (coolo@kde.org)
dnl ------------------------------------------------------------------------
dnl Find a file (or one of more files in a list of dirs)
dnl ------------------------------------------------------------------------
dnl
AC_DEFUN(AC_FIND_FILE,
[
$3=NO
for i in $2;
do
for j in $1;
do
if test -r "$i/$j"; then
$3=$i
break 2
fi
done
done
])
dnl ------------------------------------------------------------------------
dnl Find the meta object compiler in the PATH, in $QTDIR/bin, and some
dnl more usual places
dnl ------------------------------------------------------------------------
dnl
AC_DEFUN(AC_PATH_QT_MOC,
[
AC_PATH_PROG(MOC, moc, "", $ac_qt_bindir:$QTDIR/bin:$QTDIR/src/moc:/usr/bin /usr/X11R6/bin:/usr/lib/qt/bin:/usr/lib/qt2/bin:/usr/local/qt/bin:$PATH)
if test -z "$MOC"; then
if test -n "$ac_cv_path_moc"; then
output=`eval "$ac_cv_path_moc --help 2>&1 | sed -e '1q' | grep Qt"`
fi
echo "configure:__oline__: tried to call $ac_cv_path_moc --help 2>&1 | sed -e '1q' | grep Qt" >&AC_FD_CC
echo "configure:__oline__: moc output: $output" >&AC_FD_CC
if test -z "$output"; then
AC_MSG_ERROR([No Qt meta object compiler (moc) found!
Please check whether you installed Qt correctly.
You need to have a running moc binary.
configure tried to run $ac_cv_path_moc and the test didn't
succeed. If configure shouldn't have tried this one, set
the environment variable MOC to the right one before running
configure.
])
fi
fi
AC_SUBST(MOC)
])
AC_DEFUN(AC_PRINT_QT_PROGRAM,
[
cat > conftest.$ac_ext <<EOF
#include "confdefs.h"
#include <qglobal.h>
#include <qapplication.h>
#include <qstyle.h>
int main() {
QStringList *t = new QStringList();
return 0;
}
EOF
])
dnl ------------------------------------------------------------------------
dnl Try to find the Qt headers and libraries.
dnl $(QT_LDFLAGS) will be -Lqtliblocation (if needed)
dnl and $(QT_INCLUDES) will be -Iqthdrlocation (if needed)
dnl ------------------------------------------------------------------------
dnl
AC_DEFUN(AC_PATH_QT,
[
LIBQT="-lqt"
AC_MSG_CHECKING([for Qt])
ac_qt_includes=NO ac_qt_libraries=NO ac_qt_bindir=NO
qt_libraries=""
qt_includes=""
AC_ARG_WITH(qt-dir,
[ --with-qt-dir=DIR where the root of Qt is installed ],
[ ac_qt_includes="$withval"/include
ac_qt_libraries="$withval"/lib
ac_qt_bindir="$withval"/bin
])
AC_ARG_WITH(qt-includes,
[ --with-qt-includes=DIR where the Qt includes are. ],
[
ac_qt_includes="$withval"
])
ac_qt_libs_given=no
AC_ARG_WITH(qt-libraries,
[ --with-qt-libraries=DIR where the Qt library is installed.],
[ ac_qt_libraries="$withval"
ac_qt_libs_given=yes
])
AC_CACHE_VAL(ac_cv_have_qt,
[#try to guess Qt locations
qt_incdirs="$QTINC /usr/lib/qt/include /usr/local/qt/include /usr/include/qt3 /usr/include/qt /usr/include /usr/lib/qt2/include /usr/X11R6/include/X11/qt $x_includes"
test -n "$QTDIR" && qt_incdirs="$QTDIR/include $QTDIR $qt_incdirs"
qt_incdirs="$ac_qt_includes $qt_incdirs"
AC_FIND_FILE(qstyle.h, $qt_incdirs, qt_incdir)
ac_qt_includes="$qt_incdir"
qt_libdirs="$QTLIB /usr/lib/qt/lib /usr/X11R6/lib /usr/lib /usr/local/qt/lib /usr/lib/qt /usr/lib/qt2/lib $x_libraries"
test -n "$QTDIR" && qt_libdirs="$QTDIR/lib $QTDIR $qt_libdirs"
if test ! "$ac_qt_libraries" = "NO"; then
qt_libdirs="$ac_qt_libraries $qt_libdirs"
fi
test=NONE
qt_libdir=NONE
for dir in $qt_libdirs; do
try="ls -1 $dir/libqt*"
if test=`eval $try 2> /dev/null`; then qt_libdir=$dir; break; else echo "tried $dir" >&AC_FD_CC ; fi
done
ac_qt_libraries="$qt_libdir"
AC_LANG_SAVE
AC_LANG_CPLUSPLUS
ac_cxxflags_safe="$CXXFLAGS"
ac_ldflags_safe="$LDFLAGS"
ac_libs_safe="$LIBS"
CXXFLAGS="$CXXFLAGS -I$qt_incdir $all_includes"
LDFLAGS="-L$x_libraries -L$qt_libdir $all_libraries"
LIBS="$LIBS $LIBQT"
AC_PRINT_QT_PROGRAM
if AC_TRY_EVAL(ac_link) && test -s conftest; then
rm -f conftest*
else
echo "configure: failed program was:" >&AC_FD_CC
cat conftest.$ac_ext >&AC_FD_CC
ac_qt_libraries="NO"
fi
rm -f conftest*
CXXFLAGS="$ac_cxxflags_safe"
LDFLAGS="$ac_ldflags_safe"
LIBS="$ac_libs_safe"
AC_LANG_RESTORE
if test "$ac_qt_includes" = NO || test "$ac_qt_libraries" = NO; then
ac_cv_have_qt="have_qt=no"
ac_qt_notfound=""
if test "$ac_qt_includes" = NO; then
if test "$ac_qt_libraries" = NO; then
ac_qt_notfound="(headers and libraries)";
else
ac_qt_notfound="(headers)";
fi
else
ac_qt_notfound="(libraries)";
fi
AC_MSG_ERROR([Qt 2 not found. Please check your installation! ]);
else
have_qt="yes"
fi
])
eval "$ac_cv_have_qt"
if test "$have_qt" != yes; then
AC_MSG_RESULT([$have_qt]);
else
ac_cv_have_qt="have_qt=yes \
ac_qt_includes=$ac_qt_includes ac_qt_libraries=$ac_qt_libraries"
AC_MSG_RESULT([libraries $ac_qt_libraries, headers $ac_qt_includes])
qt_libraries="$ac_qt_libraries"
qt_includes="$ac_qt_includes"
fi
AC_SUBST(qt_libraries)
AC_SUBST(qt_includes)
if test "$qt_includes" = "$x_includes" || test -z "$qt_includes"; then
QT_INCLUDES="";
else
QT_INCLUDES="-I$qt_includes"
all_includes="$QT_INCLUDES $all_includes"
fi
if test "$qt_libraries" = "$x_libraries" || test -z "$qt_libraries"; then
QT_LDFLAGS=""
else
QT_LDFLAGS="-L$qt_libraries"
all_libraries="$QT_LDFLAGS $all_libraries"
fi
AC_SUBST(QT_INCLUDES)
AC_SUBST(QT_LDFLAGS)
AC_PATH_QT_MOC
LIB_QT='-lqt'
AC_SUBST(LIB_QT)
])
dnl ------------------------------------------------------------------------
dnl Find libz (required by libpng)
dnl ------------------------------------------------------------------------
dnl
AC_DEFUN(AC_FIND_ZLIB,
[
AC_MSG_CHECKING([for libz])
AC_CACHE_VAL(ac_cv_lib_z,
[
AC_LANG_C
ac_save_LIBS="$LIBS"
LIBS="$all_libraries -lz $LIBSOCKET"
ac_save_CFLAGS="$CFLAGS"
CFLAGS="$CFLAGS $all_includes"
AC_TRY_LINK(dnl
[
#include<zlib.h>
],
[return (zlibVersion() == ZLIB_VERSION); ],
eval "ac_cv_lib_z='-lz'",
eval "ac_cv_lib_z=no")
LIBS="$ac_save_LIBS"
CFLAGS="$ac_save_CFLAGS"
])dnl
if eval "test ! \"`echo $ac_cv_lib_z`\" = no"; then
AC_DEFINE_UNQUOTED(HAVE_LIBZ, 1, [Define if you have libz])
LIBZ="$ac_cv_lib_z"
AC_SUBST(LIBZ)
AC_MSG_RESULT($ac_cv_lib_z)
else
AC_MSG_RESULT(no)
LIBZ=""
AC_SUBST(LIBZ)
fi
])
dnl ------------------------------------------------------------------------
dnl Find libpng (required by Qt 2)
dnl ------------------------------------------------------------------------
dnl
AC_DEFUN(AC_FIND_PNG,
[
AC_REQUIRE([AC_FIND_ZLIB])
AC_MSG_CHECKING([for libpng])
AC_CACHE_VAL(ac_cv_lib_png,
[
ac_save_LIBS="$LIBS"
LIBS="$LIBS $all_libraries -lpng $LIBZ -lm -lX11 $LIBSOCKET"
ac_save_CFLAGS="$CFLAGS"
CFLAGS="$CFLAGS $all_includes"
AC_LANG_C
AC_TRY_LINK(dnl
[
#include<png.h>
],
[
png_structp png_ptr = png_create_read_struct( /* image ptr */
PNG_LIBPNG_VER_STRING, 0, 0, 0 );
return( png_ptr != 0 );
],
eval "ac_cv_lib_png='-lpng $LIBZ -lm'",
eval "ac_cv_lib_png=no"
)
LIBS="$ac_save_LIBS"
CFLAGS="$ac_save_CFLAGS"
])dnl
if eval "test ! \"`echo $ac_cv_lib_png`\" = no"; then
AC_DEFINE_UNQUOTED(HAVE_LIBPNG, 1, [Define if you have libpng])
LIBPNG="$ac_cv_lib_png"
AC_SUBST(LIBPNG)
AC_MSG_RESULT($ac_cv_lib_png)
else
AC_MSG_RESULT(no)
LIBPNG=""
AC_SUBST(LIBPNG)
fi
])

File diff suppressed because it is too large Load Diff

View File

@ -1,32 +0,0 @@
# Process this file with autoconf to produce a configure script.
AC_INIT(FULL-PACKAGE-NAME, VERSION, BUG-REPORT-ADDRESS)
AC_LANG(C++)
AC_CONFIG_SRCDIR([Test_optmap.cc])
AC_ARG_WITH(qt, AC_HELP_STRING([--with-qt], [use Qt gui (default no)]),
[ac_use_qt=yes], [ac_use_qt=no])
# Checks for programs.
AC_PROG_CXX
# AC_PROG_INSTALL
# Checks for libraries.
if test "$ac_use_qt" = yes; then
AC_PATH_QT
AC_DEFINE([GUI])
gui_vars='$(gui_objs)'
gui_docsrc='$(gui_docsrc)'
qt_lib='-lqt'
fi
AC_SUBST(gui_vars)
AC_SUBST(gui_docsrc)
AC_SUBST(qt_lib)
# Checks for header files.
AC_CHECK_HEADERS([sstream])
# Checks for typedefs, structures, and compiler characteristics.
# Checks for library functions.
AC_CONFIG_FILES([Makefile])
AC_OUTPUT

View File

@ -1,313 +0,0 @@
#include <algorithm>
#include "gui.h"
#include "unit++.h"
#ifdef HAVE_SSTREAM
#include <sstream>
#endif
using namespace unitpp;
using namespace std;
#ifdef GUI
static const char* const img_error[] = {
"14 14 2 1",
". c #ff0000",
"# c #ffffff",
"...########...",
"....######....",
".....####.....",
"#.....##.....#",
"##..........##",
"###........###",
"####......####",
"####......####",
"###........###",
"##..........##",
"#.....##.....#",
".....####.....",
"....######....",
"...########..."};
static const char* const img_fail[] = {
"14 14 2 1",
"# c #ff0000",
". c #ffffff",
"..............",
".##........##.",
".###......###.",
"..###....###..",
"...###..###...",
"....######....",
".....####.....",
".....####.....",
"....######....",
"...###..###...",
"..###....###..",
".###......###.",
".##........##.",
".............."};
static const char* const img_ok[] = {
"14 14 3 1",
"# c #00ff00",
"a c #00ff6a",
". c #ffffff",
"..........###.",
".........###..",
"........#a#...",
"........aa#...",
".......#aa....",
".......#a.....",
"......#aa.....",
"#.....aa#.....",
"###..#a#......",
".##.##a.......",
"..#aaa#.......",
"...#aa#.......",
"....##........",
".....#........"};
static const char* const img_empty[] = {
"14 14 2 1",
". c #f0f0f0",
"# c #ffffff",
"..............",
".############.",
".############.",
".############.",
".############.",
".############.",
".############.",
".############.",
".############.",
".############.",
".############.",
".############.",
".############.",
".............."};
cnt_item::cnt_item(QWidget* par, const QString& txt, const QColor& col,
const char* name)
: QHBox(par, name), v(0)
{
setSpacing(3);
setMargin(5);
val = new QLabel("0", this);
val->setAlignment(QLabel::AlignVCenter | QLabel::AlignRight);
QPalette pal(val->palette());
QColorGroup cg(pal.active());
cg.setColor(QColorGroup::Foreground, col);
pal.setActive(cg);
val->setPalette(pal);
label = new QLabel(txt, this);
}
void cnt_item::value(int iv)
{
v = iv;
val->setNum(v);
}
void cnt_item::inc()
{
value(v+1);
}
cnt_line::cnt_line(const QString& txt, QWidget* par, const char* name)
: QHBox(par, name)
{
label = new QLabel(txt, this);
QFont font(label->font());
font.setBold(true);
label->setFont(font);
cnts[0] = new cnt_item(this, "Total");
cnts[1] = new cnt_item(this, "OK", green);
cnts[2] = new cnt_item(this, "Fail", red);
cnts[3] = new cnt_item(this, "Error", red);
setSizePolicy(QSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred));
}
void cnt_line::max(int m) { cnts[id_max]->value(m); }
void cnt_line::inc_ok() { cnts[id_ok]->inc(); }
void cnt_line::inc_fail() { cnts[id_fail]->inc(); }
void cnt_line::inc_error() { cnts[id_error]->inc(); }
void cnt_line::reset()
{
for (int i = id_ok; i < n_id; ++i)
cnts[i]->value(0);
}
res_stack::res_stack(const QString& txt, QWidget* par, const char* name)
: QVBox(par, name)
{
cnts = new cnt_line(txt, this, name);
bar = new QProgressBar(this);
setSizePolicy(QSizePolicy(QSizePolicy::Preferred, QSizePolicy::Preferred));
}
void res_stack::max(int v)
{
cnts->max(v);
bar->setTotalSteps(v);
}
void res_stack::inc_progress(bool err)
{
QPalette pal(bar->palette());
QColorGroup cg(pal.active());
QColor red(255,0,0);
QColor green(0,244,0);
cg.setColor(QColorGroup::Highlight, err ? red : green);
cg.setColor(QColorGroup::HighlightedText, black);
pal.setActive(cg);
pal.setInactive(cg);
pal.setDisabled(cg);
bar->setPalette(pal);
bar->setProgress(bar->progress()+1);
}
void res_stack::reset() {
cnts->reset();
bar->setProgress(0);
}
void res_stack::inc_ok() { cnts->inc_ok(); inc_progress(false); }
void res_stack::inc_fail() { cnts->inc_fail(); inc_progress(true); }
void res_stack::inc_error() { cnts->inc_error(); inc_progress(true); }
QHBox* behave(QHBox* box, bool x_expand, bool y_expand)
{
box->setSizePolicy(QSizePolicy(
x_expand ? QSizePolicy::Preferred : QSizePolicy::Maximum,
y_expand ? QSizePolicy::Preferred : QSizePolicy::Maximum));
box->setFrameShape(QFrame::StyledPanel);
box->setFrameShadow(QFrame::Raised);
box->setMargin(11);
box->setSpacing(6);
return box;
}
void node::setImg()
{
static QPixmap i_emp((const char**)img_empty);
static QPixmap i_ok((const char**)img_ok);
static QPixmap i_fail((const char**)img_fail);
static QPixmap i_err((const char**)img_error);
static QPixmap* imgs[] = { &i_emp, &i_ok, &i_fail, &i_err };
item->setPixmap(0, *(imgs[st]));
if (st > is_ok)
for (QListViewItem* ip = item; ip != 0; ip = ip->parent())
ip->setOpen(true);
};
node::node(suite_node* par, test& t)
: item(new QListViewItem(par->lvi(), t.name().c_str())), t(t), st(none)
{
par->add_child(this);
setImg();
}
node::node(gui* gp, test& t)
: item(new QListViewItem(gp->test_tree(), t.name().c_str())), t(t), st(none)
{
setImg();
item->setOpen(true);
}
void node::run()
{
for (QListViewItem* ip=item->firstChild(); ip != 0; ip=item->firstChild())
delete ip;
try {
t();
status(is_ok);
emit ok();
} catch (assertion_error& e) {
status(is_fail);
show_error(e);
emit fail();
} catch (exception& e) {
status(is_error);
show_error(e.what());
emit error();
} catch (...) {
status(is_error);
show_error("unknown ... exception");
emit error();
}
}
void node::show_error(assertion_error& e)
{
#ifdef HAVE_SSTREAM
ostringstream oss;
oss << e;
show_error(oss.str().c_str());
#else
show_error(e.what()); // not well, but some sign
#endif
}
void node::show_error(const char* msg)
{
QListViewItem* elvi = new QListViewItem(item, msg);
elvi->setSelectable(false);
}
suite_node::suite_node(suite_node* par, suite& t) : node(par, t) { }
suite_node::suite_node(gui* par, suite& t) : node(par, t) { }
void suite_node::run()
{
status(is_ok);
for (cctyp::iterator p = cc.begin(); p != cc.end(); ++p) {
(*p)->run();
status(max(status(), (*p)->status()));
}
switch (status()) {
case is_ok: emit ok(); break;
case is_fail: emit fail(); break;
case is_error: emit error(); break;
}
}
gui::gui(QApplication& app, QWidget* par, const char* name)
: QVBox(par, name), app(app)
{
setMargin(6);
setSpacing(3);
tree = new QListView(behave(new QVBox(this), true, true), "tree");
tree->addColumn("Test");
tree->setFrameShadow(QListView::Sunken);
tree->setResizePolicy(QScrollView::Manual);
tree->setRootIsDecorated(true);
QVBox* f_cnts = new QVBox(this);
behave(f_cnts, true, false);
suites = new res_stack("Suites", f_cnts);
tests = new res_stack("Tests", f_cnts);
QHBox* hbox = behave(new QHBox(this), true, false);
b_run = new QPushButton("Run", hbox, "run");
b_stop = new QPushButton("Stop", hbox, "stop");
b_quit = new QPushButton("Quit", hbox, "quit");
connect(b_quit, SIGNAL(clicked()), &app, SLOT(quit()));
connect(b_run, SIGNAL(clicked()), this, SLOT(run_pressed()));
connect(b_stop, SIGNAL(clicked()), this, SLOT(stop_pressed()));
}
gui::~gui() { }
void gui::processEvents(int t)
{
app.processEvents(t);
}
void gui::reset()
{
tests->reset();
suites->reset();
}
void gui::nconnect(node* n, res_stack* rs)
{
connect(n, SIGNAL(ok()), rs, SLOT(inc_ok()));
connect(n, SIGNAL(fail()), rs, SLOT(inc_fail()));
connect(n, SIGNAL(error()), rs, SLOT(inc_error()));
}
void gui::add_test(node* n)
{
nconnect(n, tests);
}
void gui::add_suite(node* n)
{
nconnect(n, suites);
}
void gui::totSuites(int v) { suites->max(v); }
void gui::totTests(int v) { tests->max(v); }
#endif

View File

@ -1,166 +0,0 @@
#ifndef __UNITPP_GUI_H
#define __UNITPP_GUI_H
#ifdef GUI
#include "tester.h"
#include <exception>
#include <vector>
#include <qwidget.h>
#include <qcolor.h>
#include <qframe.h>
#include <qlabel.h>
#include <qlistview.h>
#include <qprogressbar.h>
#include <qhbox.h>
#include <qvbox.h>
#include <qpixmap.h>
#include <qpushbutton.h>
#include <qapplication.h>
/// \name unitpp
namespace unitpp {
/// A colored count with a unit.
class cnt_item : public QHBox
{
Q_OBJECT
private:
int v;
QLabel* val;
QLabel* label;
public:
cnt_item(QWidget* par, const QString& txt, const QColor& col = black,
const char* nam = 0);
public slots:
void value(int v);
void inc();
};
/// A line with total, ok, fail, and error counts.
class cnt_line : public QHBox
{
Q_OBJECT
private:
enum fields { id_max, id_ok, id_fail, id_error, n_id };
QLabel* label;
cnt_item* cnts[n_id];
public slots:
void max(int v);
void reset();
void inc_ok();
void inc_fail();
void inc_error();
public:
cnt_line(const QString& txt, QWidget* par = 0, const char* name = 0);
};
/// A cnt_line stacked with a progress bar.
class res_stack : public QVBox
{
Q_OBJECT
private:
cnt_line* cnts;
QProgressBar* bar;
void inc_progress(bool red);
public slots:
void max(int max);
void reset();
void inc_ok();
void inc_fail();
void inc_error();
public:
res_stack(const QString& txt, QWidget* par=0, const char* name=0);
};
class node;
/// The whole GUI box with test tree, results, and buttons.
class gui : public QVBox
{
Q_OBJECT
public:
gui(QApplication& app, QWidget* par = 0, const char* name = 0);
virtual ~gui();
QListView* test_tree() { return tree; }
void add_test(node* n);
void add_suite(node* n);
void processEvents(int t);
signals:
void run();
void stop();
public slots:
void totSuites(int v);
void totTests(int v);
void reset();
private slots:
void run_pressed() { emit run(); }
void stop_pressed() { emit stop(); }
private:
void nconnect(node* node, res_stack*);
QApplication& app;
QListView* tree;
res_stack* suites;
res_stack* tests;
QPushButton* b_run;
QPushButton* b_stop;
QPushButton* b_quit;
};
class suite_node;
// a Qt error prevents this from being a ListViewItem...
/**
* A node in the test tree. An error in Qt prevents this to be derived from
* QListViewItem, hence the separation.
*/
class node : public QObject
{
Q_OBJECT
public:
enum state { none, is_ok, is_fail, is_error };
/// Create this node under par.
node(suite_node* par, test&);
/// Get the associated QListViewItem.
QListViewItem* lvi() { return item; }
///
state status() { return st; }
signals:
/// [signal] emitted when the test succedes
void ok();
/// [signal] emitted when the test fails
void fail();
/// [signal] emitted when the test throws an exception
void error();
public slots:
/// [slot] Make the test run, and emit appropriate signals.
virtual void run();
protected:
/// Make a top level test, directly under the gui.
node(gui* par, test&);
/// Set the status of the node, including update of the displayed icon.
void status(state s) {
st = s;
setImg();
}
private:
void show_error(assertion_error& e);
void show_error(const char*);
QListViewItem* item;
test& t;
state st;
void setImg();
};
/**
* A specialized node representing a test suite.
*/
class suite_node : public node
{
typedef std::vector<node*> cctyp;
cctyp cc; // child container
public:
/// Inner suite creation.
suite_node(suite_node* par, suite&);
/// Top level suite_node.
suite_node(gui* par, suite&);
/// Test.
virtual void run();
/// Register a node below this.
void add_child(node* n) { cc.push_back(n); }
};
}
#endif
#endif

View File

@ -1,100 +0,0 @@
#ifdef GUI
#include "optmap.h"
#include "main.h"
#include "guitester.h"
#include <qapplication.h>
using namespace unitpp;
using namespace std;
class gui_test_runner : public test_runner {
virtual bool run_tests(int argc, const char** argv)
{
QApplication a(argc, const_cast<char**>(argv));
gui g(a);
g_setup setup(&g);
suite::main().visit(&setup);
a.setMainWidget(&g);
g.show();
return a.exec();
}
};
class gui_flag : public options_utils::optmap::cmd {
bool do_cmd(options_utils::optmap* om)
{
static gui_test_runner gtr;
set_tester(&gtr);
return true;
}
};
gui_hook::gui_hook()
{
options().add("g", new gui_flag());
options().alias("gui", "g");
}
g_setup::g_setup(gui* gp) : gp(gp), running(false), n_suites(0), n_tests(0)
{
connect(gp, SIGNAL(run()), this, SLOT(run()));
}
void g_setup::add_node(node* np)
{
nodes.push_back(np);
rev[np->lvi()] = np;
}
void g_setup::visit(test& t)
{
++n_tests;
node* np = new node(branch.top(), t);
add_node(np);
gp->add_test(np);
}
void g_setup::visit(suite& t)
{
++n_suites;
suite_node* np = branch.size() ? new suite_node(branch.top(), t)
: new suite_node(gp, t);
branch.push(np);
add_node(np);
gp->add_suite(np);
}
void g_setup::visit(suite& t, int)
{
branch.pop();
if (!branch.size()) {
gp->totSuites(n_suites);
gp->totTests(n_tests);
}
}
void g_setup::run()
{
if (running)
return;
running = true;
selected.clear();
find_selected(gp->test_tree()->firstChild());
if (!selected.size())
selected.push_back(rev[gp->test_tree()->firstChild()]);
gp->reset();
for (vector<node*>::iterator p = selected.begin(); p!=selected.end(); ++p) {
(*p)->run();
gp->processEvents(20);
if (!running)
break;
}
running = false;
}
void g_setup::find_selected(QListViewItem* lvi)
{
if (!lvi)
return;
if (lvi->isSelected())
selected.push_back(rev[lvi]);
else
find_selected(lvi->firstChild());
find_selected(lvi->nextSibling());
}
#endif

View File

@ -1,40 +0,0 @@
#ifndef __UNITPP__GUITESTER_H
#define __UNITPP__GUITESTER_H
#ifdef GUI
#include "tester.h"
#include "gui.h"
#include <stack>
#include <vector>
#include <qobject.h>
/// \name unitpp
namespace unitpp {
/**
* The class for setting up the GUI. It visites all the tests, and create
* nodes for them in the test tree, count them and adjust all the GUI
* elements appropriately.
*/
class g_setup : public QObject, public visitor {
Q_OBJECT
private:
gui* gp;
bool running;
int n_suites;
int n_tests;
std::stack<suite_node*> branch;
std::vector<node*> nodes, selected;
std::map<QListViewItem*, node*> rev;
void find_selected(QListViewItem*);
void add_node(node* np);
public:
g_setup(gui* gp);
virtual void visit(test&);
virtual void visit(suite&);
virtual void visit(suite&, int);
public slots:
///
void run();
};
}
#endif
#endif

View File

@ -1,69 +0,0 @@
// Copyright (C) 2001 Claus Dræby
// Terms of use are in the file COPYING
#include "main.h"
#include <algorithm>
using namespace std;
using namespace unitpp;
bool unitpp::verbose = false;
test_runner* runner = 0;
test_runner::~test_runner()
{
}
void unitpp::set_tester(test_runner* tr)
{
runner = tr;
}
int main(int argc, const char* argv[])
{
options().add("v", new options_utils::opt_flag(verbose));
options().alias("verbose", "v");
if (!options().parse(argc, argv))
options().usage();
plain_runner plain;
if (!runner)
runner = &plain;
return runner->run_tests(argc, argv) ? 0 : 1;
}
namespace unitpp {
options_utils::optmap& options()
{
static options_utils::optmap opts("[ testids... ]");
return opts;
}
bool plain_runner::run_tests(int argc, const char** argv)
{
bool res = true;
if (options().n() < argc)
for (int i = options().n(); i < argc; ++i)
res = res && run_test(argv[i]);
else
res = run_test();
return res;
}
bool plain_runner::run_test(const string& id)
{
test* tp = suite::main().find(id);
if (!tp) {
return false;
}
return run_test(tp);
}
bool plain_runner::run_test(test* tp)
{
tester tst(cout, verbose);
tp->visit(&tst);
tst.summary();
res_cnt res(tst.res_tests());
return res.n_err() == 0 && res.n_fail() == 0;
}
}

View File

@ -1,63 +0,0 @@
// Copyright (C) 2001 Claus Dræby
// Terms of use are in the file COPYING
#include <iostream>
#include "tester.h"
#include "optmap.h"
/**
* The main of a test program that executes the main test suite and then
* reports the summary.
*
* A #-v# or #--verbose# will turn on verbose, that reports succesful test
* cases; the default behaviour is to report only those that fails.
*/
int main(int argc, const char* argv[]);
/// @name{unitpp}
namespace unitpp {
/**
* The verbose flag, in case somebody wants to piggyback it with more
* meaning.
*/
extern bool verbose;
/**
* A runner is the base class for the objects that actually processes the
* tests from main. Main simply invokes the run_tests method of the current
* test runner.
* \Ref{main}
*/
class test_runner {
public:
virtual ~test_runner();
/**
* run all the tests with arguments in the argc, argv set
*/
virtual bool run_tests(int argc, const char** argv) = 0;
};
/**
* Sets the test_runner to be used in testing. This hook allows another
* tester to hook into the main function and replace the traditional tester.
*/
void set_tester(test_runner*);
/// A plain test runner for the ordinary text version.
class plain_runner : public test_runner {
public:
/// Run the tests specified in argv, starting at i.
virtual bool run_tests(int argc, const char** argv);
private:
/**
* Run a test found in the suite::main() test by id. If id is empty run the
* main test.
* @name run_test-id
* @return true, if the test was totally succesful.
*/
bool run_test(const std::string& id = "");
/// Run the test and return true if succesful. @see{run_test-id}
bool run_test(test*);
/// find the test with the given id
test* find_test(const std::string& id);
};
}

View File

@ -1,4 +0,0 @@
// This header preserves compatibility with old unit++ versions.
//
// Use of this is deprecated, use unit++/optmap.h directly
#include <unit++/optmap.h>

View File

@ -1,145 +0,0 @@
// Copyright (C) 2001 Claus Dræby
// Terms of use are in the file COPYING
#include <iostream>
#include <cstdlib>
#include "optmap.h"
using namespace std;
using namespace options_utils;
optmap::optmap(const char* usage)
: i(1), prog("program"), tail(usage)
{
}
optmap::~optmap()
{
for (group_t::iterator p = group.begin(); p != group.end(); ++p)
delete p->first;
}
optmap& optmap::add(const char* c, cmd* h)
{
if (cmds.find(c) != cmds.end())
throw invalid_argument(string("duplicated option: ")+c);
cmds[c] = h;
if (group[h].size() == 0)
gvec.push_back(h);
group[h].push_back(c);
return *this;
}
optmap& optmap::alias(const char* new_opt, const char* old_opt)
{
cmd* h = cmds[old_opt];
if (!h)
throw invalid_argument(string("no alias: ")+old_opt);
return add(new_opt, h);
}
bool optmap::parse(int c, const char** v)
{
argc = c;
argv = v;
prog = argv[0];
for (; i < argc; ++i) {
multichar = false;
const char* s = argv[i];
size_t l = strlen(s);
if (*s != '-' || l == 1)
return true;
if (s[1] == '-') {
if (l == 2) { // end of options marker `--'
++i;
return true;
}
if (!do_cmd(s+2))
return false;
} else {
char cmd[2];
cmd[1] = '\0';
multichar = l > 2;
first_multi = true;
for (const char* p = s+1; *p; ++p) {
cmd[0] = *p;
if (!do_cmd(cmd))
return false;;
first_multi = false;
if (!multichar) // get_arg used it
break;
}
}
}
return true;
}
const char* optmap::get_arg()
{
if (multichar) {
if (!first_multi) {
cerr << "internal option requires argument " << argv[i] << endl;
return 0;
}
multichar = false;
return argv[i]+2;
}
return i < argc - 1 ? argv[++i] : 0;
}
void optmap::usage(bool abort)
{
cerr << "usage: " << prog;
for (gvec_t::iterator p = gvec.begin(); p != gvec.end(); ++p) {
cmd* h = *p;
vector<string>& v(group[h]);
string arg = h->arg();
bool need_par = arg.size() > 0 && v.size() > 1;
bool first = true;
cerr << " [";
if (need_par)
cerr << "(";
for (vector<string>::iterator s = v.begin(); s != v.end(); ++s) {
cerr << (first ? " " : " | ") << (s->size() != 1 ? "--":"-") << *s;
first = false;
}
if (need_par)
cerr << ")";
if (arg.size())
cerr << ' ' << arg;
cerr << " ]";
}
cerr << (tail.size() ? " " : "") << tail << endl;
if (abort)
exit(1);
}
bool optmap::do_cmd(const string& opt)
{
cmd* c = cmds[opt];
if (!c) {
cerr << "unknown option: " << opt << endl;
return false;
}
return c->do_cmd(this);
}
bool opt_int::do_cmd(optmap* om)
{
const char* arg = om->get_arg();
if (!arg)
return false;
char* end;
int v = strtol(arg, &end, 10);
if (*end) {
cerr << "failed to parse int argument: " << arg << endl;
return false;
}
val = v;
return true;
}
bool opt_string::do_cmd(optmap* om)
{
const char* arg = om->get_arg();
if (!arg)
return false;
val = arg;
return true;
}

View File

@ -1,125 +0,0 @@
// Copyright (C) 2001 Claus Dræby
// Terms of use are in the file COPYING
#ifndef __UNITPP__OPTMAP_H
#define __UNITPP__OPTMAP_H
#include <string>
#include <map>
#include <vector>
#include <stdexcept>
/**
* The home of \Ref{optmap}. This is a unified way of handling commang line
* arguments, and suitable usage replies when things goes badly.
*/
namespace options_utils {
/**
* A argument option handler, based on the Command pattern. Each option is
* associated with a handling command object.
*
* The map keeps the reverse association as well, to allow printing of a
* using line.
*/
class optmap {
public:
/**
* The base for all option handlers.
*
* To handle a new kind of commands, just derive a class from this an
* overload the methods to do the work.
*/
struct cmd {
/**
* Performing the work associated with the option.
*
* To obtain an argument see \Ref{get_arg}
* @return true if the parsing was succesfull
*/
virtual bool do_cmd(optmap* om) = 0;
/// return the name of the argument needed by \Ref{usage}
virtual std::string arg() { return std::string(); }
virtual ~cmd() {}
};
/**
* The very simple constructor for an optmap object. Please note that
* copying of optmaps are not supported.
* @param usage The tail of the usage string to follow the options
*/
optmap(const char* usage = "");
~optmap();
/**
* Adds an option that invokes the command handler.
*
* This is the low level work horse for all the add methods. All the
* other adds works by adding appropriate cmd objects for doing the work.
*
* @param o
* The option name. If the length of the option is 1 it will be an old
* fashion option, otherwise it will be a GNU stype long option
* (--long-opt).
* @param h
* The pointer to the handler. The optmap assumes ownership of the
* pointer and delete it in the destructor.
*
* @return *this
*/
optmap& add(const char* o, cmd* h);
/// Adds an alias for an option.
optmap& alias(const char* new_opt, const char* old_opt);
/**
* Parse the command line.
* @return true if the parse is valid, false otherwise.
*/
bool parse(int argc, const char** argv);
/// Gets the index for the first non option argument
int n() { return i; }
/// display a usage string and abort()
void usage(bool abort = true);
/// get the argument of an option; mainly for cmd implementations.
const char* get_arg();
private:
int i;
const char* prog;
int argc;
const char** argv;
bool multichar; // doing a multichar, -pdf --> -p -d -f
bool first_multi;
optmap(const optmap& o);
optmap& operator=(const optmap&);
bool do_cmd(const std::string& opt);
std::string tail;
typedef std::map<std::string, cmd*> cmds_t;
cmds_t cmds;
typedef std::vector<cmd*> gvec_t;
gvec_t gvec;
typedef std::map<cmd*, std::vector<std::string> > group_t;
group_t group;
};
/// A cmd handler that can set a boolean flag.
class opt_flag : public optmap::cmd {
bool& flg;
public:
/// Just give it the bool you want set if the flag is present.
opt_flag(bool& flg) : flg(flg) {}
virtual bool do_cmd(optmap*) { flg = true; return true; }
};
/// A cmd handler that can get an integer value.
class opt_int : public optmap::cmd {
int& val;
public:
/// just give it an int variable that the flag argument can be assigned to.
opt_int(int& val) : val(val) {}
virtual bool do_cmd(optmap* om);
virtual std::string arg() { return std::string("<int>"); }
};
/// A cmd handler for a string
class opt_string : public optmap::cmd {
std::string& val;
public:
/// Give it a string that the flag arg should be assigned to.
opt_string(std::string& val) : val(val) {}
virtual bool do_cmd(optmap* om);
virtual std::string arg() { return std::string("<string>"); }
};
}
#endif

View File

@ -1,74 +0,0 @@
// Copyright (C) 2001 Claus Dræby
// Terms of use are in the file COPYING
#include <typeinfo>
#include <iostream>
#include "tester.h"
using namespace std;
using namespace unitpp;
void tester::summary()
{
os << "Tests [Ok-Fail-Error]: [" << n_test.n_ok() << '-'
<< n_test.n_fail() << '-' << n_test.n_err() << "]\n";
}
void tester::visit(test& t)
{
try {
t();
n_test.add_ok();
write(t);
} catch (assertion_error& e) {
n_test.add_fail();
write(t, e);
} catch (exception& e) {
n_test.add_err();
write(t, e);
} catch (...) {
n_test.add_err();
write(t, 0);
}
}
void tester::visit(suite& t)
{
if (verbose)
os << "****** " << t.name() << " ******" << endl;
accu.push(n_test);
}
void tester::visit(suite& , int)
{
res_cnt r(accu.top());
accu.pop();
if (n_test.n_err() != r.n_err())
n_suite.add_err();
else if (n_test.n_fail() != r.n_fail())
n_suite.add_fail();
else
n_suite.add_ok();
}
void tester::write(test& t)
{
if (verbose)
disp(t, "OK");
}
void tester::disp(test& t, const string& status)
{
os << status << ": " << t.name() << endl;
}
void tester::write(test& t, assertion_error& e)
{
disp(t, "FAIL");
os << e << '\n';
}
void tester::write(test& t, std::exception& e)
{
disp(t, "ERROR");
os << " : [" << typeid(e).name() << "] " << e.what() << '\n';
}
void tester::write(test& t, int )
{
disp(t, "ERROR");
os << " : " << "unknown exception" << '\n';
}

View File

@ -1,77 +0,0 @@
// Copyright (C) 2001 Claus Dræby
// Terms of use are in the file COPYING
#ifndef _UNITPP_TESTER_H
#define _UNITPP_TESTER_H
#include <stack>
#ifdef __UNITPP
#include "unit++.h"
#else
#include <unit++/unit++.h>
#endif
namespace unitpp {
/// A mostly internal class for keeping score.
class res_cnt {
int ok, fail, err;
public:
/// Create a 0 count.
res_cnt() : ok(0), fail(0), err(0) {}
/// Count one ok.
void add_ok() { ++ok; }
/// Count one fail.
void add_fail() { ++fail; }
/// Count one error.
void add_err() { ++err; }
/// get ok count.
int n_ok() { return ok; }
/// get fail count.
int n_fail() { return fail; }
/// get error count.
int n_err() { return err; }
/// get total count.
int n() { return ok+fail+err; }
};
/**
* The standard text based tester. It implements the visitor pattern for the
* test and suite classes, and executes each test case in a depth first
* traversal, toting the score of test cases.
*
* The class might be used for test executers aimed at other environments,
* e.g. a GUI based version.
*
* Please note that this class is automagically instantiated by the main
* method supplied in the library. This means that you might very well do all
* your testing without directly laying hans on this fellow.
*/
class tester : public visitor {
std::ostream& os;
bool verbose; // list succeded tests
std::stack<res_cnt> accu;
res_cnt n_suite, n_test;
void disp(test& t, const std::string&);
void write(test& t);
void write(test& t, assertion_error& e);
void write(test& t, std::exception& e);
void write(test& t, int dummy);
public:
/**
* Create a text tester.
* \param os the stream to write results to.
* \param verbose whether to report on succesful tests
*/
tester(std::ostream& os, bool verbose = false) : os(os), verbose(verbose) {}
/// Get the score for tests
res_cnt res_tests() { return n_test; }
/// Get the score for suites
res_cnt res_suites() { return n_suite; }
/// Write the summary
virtual void summary();
/// Part of the visitor pattern.
virtual void visit(test&);
/// Part of the visitor pattern.
virtual void visit(suite&);
/// Part of the visitor pattern; visit to suite after children.
virtual void visit(suite& t, int);
};
}
#endif

View File

@ -1,4 +0,0 @@
// This header preserves compatibility with old unit++ versions.
//
// Use of this is deprecated, use unit++/unit++.h directly
#include <unit++/unit++.h>

View File

@ -1,27 +0,0 @@
.hy 0
.if n .na
.TH UNIT++ 1 2002-02-23 "Unit++ 1.2"
.UC
.SH NAME
\fBunit++\fB \- run a set of tests
.SH SYNOPSIS
.BI "unit++ [-v|--verbose] [-g|--gui] [testid...]
.SH DESCRIPTION
.B unit++
(the usual name) is the resulting program from compiling a set of unit++
tests, and linking them with the
.B unit++(3)
library supplied main function to obtain an executable test suite.
Each test in the test tree has an id, and it is possible to start only some
of the tests by naming them in the form id1.id2.id3.
The GUI option is only available if the library was compiled with GUI
support, and the tests has actually linked the GUI stuff as well. Otherwise
the -g option will provoke an error. Otherwise it will give a Qt based GUI
that allows running of individual tests, with a nice green (or less nice red)
bar that shows success (or failure).
.SH AUTHOR
Claus Dræby <azhrarn@users.sourceforge.net>
.SH SEE ALSO
.BR unit++ (3).

View File

@ -1,130 +0,0 @@
.hy 0
.if n .na
.TH UNIT++ 3 2002-02-23 "Unit++ 1.2"
.UC
.SH NAME
\fBunit++\fB: \fBtest\fB, \fBsuite\fb, \fBtestcase\fB \- test framework for C++.
.SH SYNOPSIS
.B #include <unit++/unit++.h>
.br
.B using namespace unitpp;
.br
.B using namespace std;
.sp
.BI "test::test(string " name );
.sp
.B virtual void test::operator()();
.sp
.B class suite : public test
.sp
.BI "suite::suite(string " name );
.sp
.BI "static suite& suite::main();"
.sp
.BI "void suite::add(const string& " id ", const testcase& " t );
.sp
.BI "template<typename " C "> "
.br
.BI " testcase::testcase(" C "* " par ", const string& " name ", "
.br
.BI " typename test_mfun<" C ">::mfp " fp ");"
.sp
.BI "testcase::testcase(test* " t );
.sp
.BI "fail(const string& " msg );
.sp
.BI "template<typename " A "> "
.br
.BI " void assert_true(const string& " msg ", " A " " assertion );
.sp
.BI "template<typename " T1 ", typename " T2 "> "
.br
.BI " void assert_eq(const string& " msg ", " T1 " " exp ", " T2 " " got );
.sp
.BI "gui_hook::gui_hook();"
.SH LIBRARIES
.B -lunit++
.SH DESCRIPTION
.B unit++
is a fremework that allows creation and execution of C++ unit tests. Each
test is an instance of the
.B test
class, and is managed by an instance of the
.B testcase
class. The actual takes place by invoking each test as function, that is
calling the virtual operator(). However, the usual way of making tests is by
using a class derived from the
.B suite
class to wrap a number of releated tests, Each test then
becomes a member function in the class, and the testcase instance is
constructed by using the
.B member function template constructor.
Each test suite class is usually placed in an anonymous namespace to allow
the all to be named Test, as in the example below. Since the
.B main
method of the library runs a global test suite each suite must add itself to
this global tree. This is done by invoking
.B add
on the test suite object obtained by
.B suite::main().
The assert templates allows the tests to check conditions;
.B assert_true
checks a truth value, that is it fails if !
.I assertion
evaluates to true;
.B assert_eq asserts equality by use of == between two objects, both of which
must be of types that can be written to a stream by use of <<.
.B fail
simply fails a test.
The
.B gui_hook
class is the hook for allowing a test to use the Qt gui for the test program.
A test program must have exactly one global object of type gui_hook in order
to enable the gui, Even when compiled without gui support, creating a
gui_hook is ok, but it will only have effect if gui support was enabled when
the library was compiled.
.SH EXAMPLES
.nf
#include <unit++/unit++.h>
using namespace std;
using namespace unitpp;
namespace {
class Test : public suite
{
char* p = "Hej";
string s("mor");
void t1()
{
assert_true("pointer is not 0", p);
}
void t2()
{
assert_eq("Texts match", string("Mor"), s);
}
public:
Test() : suite("Yet another test suite")
{
suite::main().add("demo", this);
add("t1", testcase(this, "T1", &Test::t1));
add("t2", testcase(this, "T2", &Test::t2));
}
} * theTest = new Test();
}
.fi
.SH NOTE
Each test suite runs all its tests in the same instance. That means that the
above example will invoke first t1 and then t2 in the same object. Hence any
side effects on the Test object that a test function has survives to the
subsequent tests in the same object. This behaviour is directly opposite to
how the original unit test framework junit treats test suites. There are
however compelling C++ reasons why it must be so, and once known it might
even be used to an advantage from time to time.
.SH AUTHOR
Claus Dræby <azhrarn@users.sourceforge.net>
.SH SEE ALSO
.BR unit++ (1).

View File

@ -1,93 +0,0 @@
// Copyright (C) 2001 Claus Dræby
// Terms of use are in the file COPYING
#include <algorithm>
#include <functional>
#include "unit++.h"
using namespace unitpp;
using namespace std;
#ifndef GUI
gui_hook::gui_hook() { }
#endif
void test::visit(visitor* v)
{
v->visit(*this);
}
testcase::testcase(test* t)
: cnt(new size_t(1)), tst(t)
{
}
testcase::testcase(const testcase& t)
: cnt(t.cnt), tst(t.tst)
{
(*cnt)++;
}
void testcase::dec_cnt()
{
if (--(*cnt) == 0) {
delete cnt;
delete tst;
}
}
testcase::~testcase()
{
dec_cnt();
}
testcase& testcase::operator=(const testcase& t)
{
++*(t.cnt);
dec_cnt();
cnt = t.cnt;
tst = t.tst;
return *this;
}
suite& suite::main()
{
static suite instance("top");
return instance;
}
test* suite::get_child(const string& id)
{
vector<string>::iterator p = std::find(ids.begin(), ids.end(), id);
if (p != ids.end())
return &(static_cast<test&>(tests[p - ids.begin()]));
return 0;
}
vector<string> unitpp::vectorize(const string& str, char c)
{
vector<string> res;
string::const_iterator s, p;
for (s = str.begin(); s != str.end(); ) {
p = find(s, str.end(), c);
res.push_back(string(s, p));
s = (p == str.end()) ? p : p + 1;
}
return res;
}
test* suite::find(const string& id)
{
vector<string> ss(vectorize(id, '.'));
test* tp = this;
for (vector<string>::iterator p = ss.begin(); p != ss.end(); ++p)
if (!(tp = tp->get_child(*p)))
break;
return tp;
}
void suite::add(const string& id, const testcase& t)
{
ids.push_back(id);
tests.push_back(t);
}
void suite::visit(visitor* v)
{
v->visit(*this);
for_each(tests.begin(), tests.end(),
bind2nd(mem_fun_ref(&testcase::visit), v));
v->visit(*this, 0);
}
void unitpp::assertion_error::out(ostream& os) const
{
os << msg << string(" [assertion failed]");
}

View File

@ -1,344 +0,0 @@
// Copyright (C) 2001 Claus Dræby
// Terms of use are in the file COPYING
#ifndef __TEST_FW_H_
#define __TEST_FW_H_
#include <vector>
#include <string>
#include <map>
#include <iostream>
#include "optmap.h"
/**
* The unitpp name space holds all the stuff needed to use the unit++ testing
* framework.
*
* The normal way to make a test is like this:
*
\begin{verbatim}
#include<unit++/unit++.h>
using namespace unitpp;
// use anonymous namespace so all test classes can be named Test
namespace {
class Test : public suite {
void test1()
{
// do test stuff
assert_true("message", exp1); // exp1 should be true
assert_eq("another msg", 123456, exp2); // exp2 should be 123456
// ...
}
void test2()
{
// do something that provokes exception out_of_range
}
public:
Test() : suite("appropriate name for test suite")
{
// any setup you need
add("id1", testcase(this, "Test 1", &Test::test1));
// make a testcase from the method
testcase tc(this, "Test 2", &Test::test2);
// add a testcase that expects the exception
add("id2", exception_case<out_of_range>(tc));
// add the suite to the global test suite
suite::main().add("id", this);
}
} * theTest = new Test(); // by new, since testcase claims ownership
}
\end{verbatim}
*
* In order to make an executable test, simply link the above code against
* libunit++, something like
*
* #g++ -o test++ mytest.cc -L <location of libunit++> -lunit++#
*
* This will generate a test called #test++# and the standard behaviour for a
* test. Note that most shells have #test# defined as a shell builtin which
* makes it a moderately bad name for a program, since it is rather hard to
* get executed, hence #test++#.
* @see main
*/
namespace unitpp {
class visitor;
/**
* The heart of a test system: A test. The test is meant as a base class for
* the tests that a client want performed. This means that all tests are to
* be pointers dynamically allocated. However, the test system takes
* responsibilities for freeing them again.
*
* The function call overload mechanism is used for the executable part of
* the test.
*/
class test {
std::string nam;
public:
/// A test just needs a name
test(const std::string& name) : nam(name) {}
virtual ~test() {}
/// The execution of the test
virtual void operator()() = 0;
virtual void visit(visitor*);
virtual test* get_child(const std::string&) { return 0; }
std::string name() const { return nam; }
};
/**
* A test that is implemented by a member function.
*/
template<typename C>
class test_mfun : public test {
public:
typedef void (C::*mfp)();
/// An object, a name, and a pointer to a member function.
test_mfun(C* par, const std::string& name, mfp fp)
: test(name), par(par), fp(fp)
{}
/// Executed by invoking the function in the object.
virtual void operator()()
{
(par->*fp)();
}
private:
C* par;
mfp fp;
};
/**
* A ref counted reference to a test. This is what test suites are composed
* of, and what ensures destruction.
*/
class testcase {
size_t* cnt;
test* tst;
void dec_cnt();
public:
/// Simply wrap -- and own -- a test.
testcase(test* t);
/// Keep the ref count
testcase(const testcase& tr);
/**
* Make a testcase from a class and a member function.
*
* The normal usage is inside some test suite class Test:
*
* #add("id", testcase(this, "Testing this and that", &Test::test))#
*
* to make a test that invokes the test method on the instance of the
* suite class.
* \Ref{test_mfun}
*/
template<typename C>
testcase(C* par, const std::string& name, typename test_mfun<C>::mfp fp)
: cnt(new size_t(1)), tst(new test_mfun<C>(par, name, fp))
{ }
~testcase();
/// Assignment that maintains reference count.
testcase& operator=(const testcase&);
void visit(visitor* vp) const { tst->visit(vp); }
operator test& () { return *tst; }
operator const test& () const { return *tst; }
};
/**
* A wrapper class for the testcase class that succedes if the correct
* exception is generated.
*/
template<typename E>
class exception_test : public test {
public:
/**
* The constructor needs a testcase to wrap. This exception_test will
* fail unless the wrapped testcase generates the exception.
*
* The name of the exception_test is copied from the wrapped test.
*/
exception_test(const testcase& tc)
: test(static_cast<const test&>(tc).name()), tc(tc) {}
~exception_test() {}
/// Runs the wrapped test, and fails unless the correct exception is thrown.
virtual void operator()();
private:
testcase tc;
};
/**
* Generate a testcase that expects a specific exception from the testcase it
* wraps. It can be used something like
*
* #testcase tc(this, "Test name", &Test::test);#
*
* #add("ex", exception_case<out_of_range>(tc));#
*
* The name of the exception_case is copied from the wrapped testcase, and
* the exception_case will execute the tc test case and report a failure
* unless the #out_of_range# exception is generated.
*/
template<typename E>
testcase exception_case(const testcase& tc)
{
return testcase(new exception_test<E>(tc));
}
/**
* Splits the string by char c. Each c will generate a new element in the
* vector, including leading and trailing c.
*/
extern std::vector<std::string> vectorize(const std::string& str, char c);
/**
* A suite is a test that happens to be a collection of tests. This is an
* implementation of the Composite pattern.
*/
class suite : public test {
std::vector<std::string> ids;
std::vector<testcase> tests;
public:
/// Make an empty test suite.
suite(const std::string& name) : test(name) {}
virtual ~suite() {};
/// Add a testcase to the suite.
void add(const std::string& id, const testcase& t);
/**
* Get a child with the specified id.
* @return 0 if not found.
*/
virtual test* get_child(const std::string& id);
/// An empty implementation.
virtual void operator()() {}
/// Allow a visitor to visit a suite node of the test tree.
void visit(visitor*);
/// Get a reference to the main test suite that the main program will run.
static suite& main();
// Splits the string by dots, and use each id to find a suite or test.
test* find(const std::string& id);
};
/**
* The visitor class is a base class for classes that wants to participate in
* the visitor pattern with the test hierarchi.
*
* This is a slightly extended visitor pattern implementation, intended for
* collaboration with the Composite pattern. The aggregate node (here the
* suite node) is visited twice, before and after the children are visited.
* This allows different algorithms to be implemented.
*/
class visitor {
public:
virtual ~visitor() {}
/// Visit a test case, that is not a suite.
virtual void visit(test&) = 0;
/// Visit a suite node before the children are visited.
virtual void visit(suite&) {};
/**
* Visit a suite after the children are visited
*/
virtual void visit(suite&, int dummy) = 0; // post childs
};
/// The basic for all failed assert statements.
class assertion_error : public std::exception
{
std::string msg;
public:
/// An assertion error with the given message.
assertion_error(const std::string& msg) : msg(msg) {}
///
std::string message() const { return msg; }
virtual ~assertion_error() throw () {}
/**
* The virtual method used for operator<<.
*/
virtual void out(std::ostream& os) const;
};
/**
* This exception represents a failed comparison between two values of types
* T1 and T2. Both the expected and the actually value are kept.
*/
template<class T1, class T2>
class assert_value_error : public assertion_error
{
T1 exp;
T2 got;
public:
/// Construct by message, expected and gotten.
assert_value_error(const std::string& msg, T1& exp, T2& got)
: assertion_error(msg), exp(exp), got(got)
{
}
virtual ~assert_value_error() throw () {}
/**
* Specialized version that requires both T1 and T2 to support
* operator<<(ostream&, Tn).
*/
virtual void out(std::ostream& os) const
{
os << message() << " [expected: `" << exp << "' got: `" << got << "']";
}
};
/// The test was not succesful.
inline void fail(const std::string& msg)
{
throw assertion_error(msg);
}
template<typename E>
void exception_test<E>::operator()()
{
try {
(static_cast<test&>(tc))();
fail("unexpected lack of exception");
} catch (E& ) {
// fine!
}
}
/// Assert that the assertion is true, that is fail #if (!assertion) ...#
template<class A> inline void assert_true(const std::string& msg, A assertion)
{
if (!assertion)
throw assertion_error(msg);
}
/// Assert that the two arguments are equal in the #==# sense.
template<class T1, class T2>
inline void assert_eq(const std::string& msg, T1 exp, T2 got)
{
if (!(exp == got))
throw assert_value_error<T1,T2>(msg, exp, got);
}
/*
* Put an assertion error to a stream, using the out method. The out method
* is virtual.
*/
inline std::ostream& operator<<(std::ostream& os, const unitpp::assertion_error& a)
{
a.out(os);
return os;
}
/**
* The singleton instance of the option handler of main.
*
* This allows a test to add its own flags to the resulting test program, in
* the following way.
*
* #bool x_flg = false;#
* #unitpp::options().add("x", new options_utils::opt_flag(x_flg));#
*
* If a -x is now given to the resulting test it will set the #x_flg#
* variable;
*/
options_utils::optmap& options();
/**
* An instance of this class hooks the GUI code into the test executable.
* Hence, make a global variable of class gui_hook to allow the -g option to
* a test.
*
* If the library is compiled without GUI support, it is still legal to
* create an instance of gui_hook, but it will not add the -g option.
*/
class gui_hook {
public:
gui_hook();
};
}
#endif

View File

@ -1,59 +0,0 @@
dnl AM_PATH_UNITPP([ACTION-IF-FOUND [, ACTION-IF-NOT-FOUND]])
dnl note to self - reference vars with $1, $2 etc
AC_DEFUN(AM_PATH_UNITPP,
[
AC_LANG_PUSH(C++)
AC_ARG_ENABLE(unitpp,
AC_HELP_STRING([--enable-unitpp-test],
[enable unit tests (default is YES if you have libunit++, else NO)]),
,
[enable_unitpp="yes"] )
AC_ARG_WITH(unitpp-prefix,
AC_HELP_STRING([--with-unitpp-prefix=DIR],
[specify the location of unit++ for unit tests]) )
if test "x$with_unitpp_prefix"="x"; then
UNITPP_CXXFLAGS="-I$with_unitpp_prefix/include"
UNITPP_LIBS="-L$with_unitpp_prefix/lib -lunit++"
else
# UNITPP_CXXFLAGS="-I/usr/local/include"
UNITPP_LIBS="-lunit++"
fi
CXXFLAGS="$CXXFLAGS $UNITPP_CXXFLAGS"
LIBS="$LIBS $UNITPP_LIBS"
if test $enable_unitpp="yes"; then
AC_CHECK_HEADER(unit++/unit++.h,
[ac_check_unitpp="yes"],
[ac_check_unitpp="no"] )
if test $ac_check_unitpp="yes"; then
AC_MSG_CHECKING(if unit++ test program compiles)
AC_TRY_LINK(
[ #include<unit++/unit++.h> ],
[ unitpp::test* test_test = new unitpp::suite("Test Suite"); ],
[ac_check_unitpp="yes"
AC_MSG_RESULT(yes) ],
[ac_check_unitpp="no"
AC_MSG_RESULT(no) ] )
fi
else
ac_check_unitpp="yes"
fi
if test $ac_check_unitpp="yes"; then
ifelse([$1], , :, [$1])
else
UNITPP_CXXFLAGS=""
UNITPP_LIBS=""
ifelse([$2], , :, [$2])
fi
AC_LANG_POP(C++)
AC_SUBST(UNITPP_CXXFLAGS)
AC_SUBST(UNITPP_LIBS)
])

View File

@ -17,77 +17,61 @@
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
// //
#include "../lib/unit++/unit++.h" #include "tests/testUtils.hpp"
#include <iostream>
#include <ostream>
#include "vmime/vmime.hpp"
#include "vmime/platforms/posix/posixHandler.hpp"
using namespace unitpp;
namespace #define VMIME_TEST_SUITE bodyPartTest
{ #define VMIME_TEST_SUITE_MODULE "Parser"
class bodyPartTest : public suite
VMIME_TEST_SUITE_BEGIN
VMIME_TEST_LIST_BEGIN
VMIME_TEST(testParse)
VMIME_TEST(testGenerate)
VMIME_TEST_LIST_END
static const vmime::string extractComponentString
(const vmime::string& buffer, const vmime::component& c)
{ {
static const vmime::string extractComponentString return vmime::string(buffer.begin() + c.getParsedOffset(),
(const vmime::string& buffer, const vmime::component& c) buffer.begin() + c.getParsedOffset() + c.getParsedLength());
{ }
return vmime::string(buffer.begin() + c.getParsedOffset(),
buffer.begin() + c.getParsedOffset() + c.getParsedLength());
}
void testParse() void testParse()
{ {
vmime::string str1 = "HEADER\r\n\r\nBODY"; vmime::string str1 = "HEADER\r\n\r\nBODY";
vmime::bodyPart p1; vmime::bodyPart p1;
p1.parse(str1); p1.parse(str1);
assert_eq("1", "HEADER\r\n\r\n", extractComponentString(str1, *p1.getHeader())); VASSERT_EQ("1", "HEADER\r\n\r\n", extractComponentString(str1, *p1.getHeader()));
assert_eq("2", "BODY", extractComponentString(str1, *p1.getBody())); VASSERT_EQ("2", "BODY", extractComponentString(str1, *p1.getBody()));
vmime::string str2 = "HEADER\n\nBODY"; vmime::string str2 = "HEADER\n\nBODY";
vmime::bodyPart p2; vmime::bodyPart p2;
p2.parse(str2); p2.parse(str2);
assert_eq("3", "HEADER\n\n", extractComponentString(str2, *p2.getHeader())); VASSERT_EQ("3", "HEADER\n\n", extractComponentString(str2, *p2.getHeader()));
assert_eq("4", "BODY", extractComponentString(str2, *p2.getBody())); VASSERT_EQ("4", "BODY", extractComponentString(str2, *p2.getBody()));
vmime::string str3 = "HEADER\r\n\nBODY"; vmime::string str3 = "HEADER\r\n\nBODY";
vmime::bodyPart p3; vmime::bodyPart p3;
p3.parse(str3); p3.parse(str3);
assert_eq("5", "HEADER\r\n\n", extractComponentString(str3, *p3.getHeader())); VASSERT_EQ("5", "HEADER\r\n\n", extractComponentString(str3, *p3.getHeader()));
assert_eq("6", "BODY", extractComponentString(str3, *p3.getBody())); VASSERT_EQ("6", "BODY", extractComponentString(str3, *p3.getBody()));
} }
void testGenerate() void testGenerate()
{ {
vmime::bodyPart p1; vmime::bodyPart p1;
p1.getHeader()->getField("Foo")->setValue(vmime::string("bar")); p1.getHeader()->getField("Foo")->setValue(vmime::string("bar"));
p1.getBody()->setContents(vmime::create <vmime::stringContentHandler>("Baz")); p1.getBody()->setContents(vmime::create <vmime::stringContentHandler>("Baz"));
assert_eq("1", "Foo: bar\r\n\r\nBaz", p1.generate()); VASSERT_EQ("1", "Foo: bar\r\n\r\nBaz", p1.generate());
} }
public: VMIME_TEST_SUITE_END
bodyPartTest() : suite("vmime::bodyPart")
{
// VMime initialization
vmime::platformDependant::setHandler<vmime::platforms::posix::posixHandler>();
add("Parse", testcase(this, "Parse", &bodyPartTest::testParse));
add("Generate", testcase(this, "Generate", &bodyPartTest::testGenerate));
suite::main().add("vmime::bodyPart", this);
}
};
bodyPartTest* theTest = new bodyPartTest();
}

View File

@ -17,126 +17,109 @@
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
// //
#include "../lib/unit++/unit++.h" #include "tests/testUtils.hpp"
#include <iostream>
#include <ostream>
#include "vmime/vmime.hpp"
#include "vmime/platforms/posix/posixHandler.hpp"
#include "tests/parser/testUtils.hpp"
using namespace unitpp;
namespace #define VMIME_TEST_SUITE datetimeTest
{ #define VMIME_TEST_SUITE_MODULE "Parser"
class datetimeTest : public suite
VMIME_TEST_SUITE_BEGIN
VMIME_TEST_LIST_BEGIN
VMIME_TEST(testParse)
VMIME_TEST(testGenerate)
VMIME_TEST(testCompare)
VMIME_TEST_LIST_END
void testParse()
{ {
void testParse() struct datetimePair
{ {
struct datetimePair vmime::string parseBuffer;
{ vmime::datetime result;
vmime::string parseBuffer; };
vmime::datetime result;
};
// Here, we can't test all the possible structures for date/time, // Here, we can't test all the possible structures for date/time,
// so we test some cases. Don't forget to add a new test case // so we test some cases. Don't forget to add a new test case
// each time you encounter a bug in date/time parsing (after // each time you encounter a bug in date/time parsing (after
// you have fixed it). // you have fixed it).
datetimePair pairs[] = datetimePair pairs[] =
{
{ /* 1 */ "Mon, 8 Nov 2004 13:42:56 +0000 (GMT)",
vmime::datetime(2004, 11, 8, 13, 42, 56, vmime::datetime::GMT) },
{ /* 2 */ "Sun, 7 Nov 2004 00:43:22 -0500 (EST)",
vmime::datetime(2004, 11, 7, 0, 43, 22, vmime::datetime::GMT_5) },
{ /* 3 */ "Thu Nov 18 12:11:16 2004",
vmime::datetime(vmime::datetime::now().getYear(), 11, 18, 12, 11, 16, vmime::datetime::GMT) },
{ /* 4 */ "Sat, 18, 2004 22:36:32 -0400",
vmime::datetime(2004, 1, 18, 22, 36, 32, vmime::datetime::GMT_4) },
{ /* 5 */ "Mon Dec 13 21:57:18 2004",
vmime::datetime(vmime::datetime::now().getYear(), 12, 13, 21, 57, 18, vmime::datetime::GMT) },
{ /* 6 */ "18 Nov 2004 21:44:54 +0300",
vmime::datetime(2004, 11, 18, 21, 44, 54, vmime::datetime::GMT3) }
};
for (unsigned int i = 0 ; i < sizeof(pairs) / sizeof(pairs[0]) ; ++i)
{
vmime::datetime d;
d.parse(pairs[i].parseBuffer);
std::ostringstream oss;
oss << (i + 1);
assert_eq(oss.str(), pairs[i].result, d);
}
}
void testGenerate()
{ {
vmime::datetime d1(2005, 7, 8, 4, 5, 6, 1 * 60 + 23); { /* 1 */ "Mon, 8 Nov 2004 13:42:56 +0000 (GMT)",
vmime::datetime(2004, 11, 8, 13, 42, 56, vmime::datetime::GMT) },
assert_eq("1", "Fri, 8 Jul 2005 04:05:06 +0123", d1.generate()); { /* 2 */ "Sun, 7 Nov 2004 00:43:22 -0500 (EST)",
} vmime::datetime(2004, 11, 7, 0, 43, 22, vmime::datetime::GMT_5) },
void testCompare() { /* 3 */ "Thu Nov 18 12:11:16 2004",
vmime::datetime(vmime::datetime::now().getYear(), 11, 18, 12, 11, 16, vmime::datetime::GMT) },
{ /* 4 */ "Sat, 18, 2004 22:36:32 -0400",
vmime::datetime(2004, 1, 18, 22, 36, 32, vmime::datetime::GMT_4) },
{ /* 5 */ "Mon Dec 13 21:57:18 2004",
vmime::datetime(vmime::datetime::now().getYear(), 12, 13, 21, 57, 18, vmime::datetime::GMT) },
{ /* 6 */ "18 Nov 2004 21:44:54 +0300",
vmime::datetime(2004, 11, 18, 21, 44, 54, vmime::datetime::GMT3) }
};
for (unsigned int i = 0 ; i < sizeof(pairs) / sizeof(pairs[0]) ; ++i)
{ {
// Date1 = Date2 vmime::datetime d;
vmime::datetime d1(2005, 4, 22, 14, 6, 0, vmime::datetime::GMT2); d.parse(pairs[i].parseBuffer);
vmime::datetime d2(2005, 4, 22, 10, 6, 0, vmime::datetime::GMT_2);
assert_eq("1.1", true, d1 == d2); std::ostringstream oss;
assert_eq("1.2", false, d1 != d2); oss << (i + 1);
assert_eq("1.3", true, d1 <= d2);
assert_eq("1.4", false, d1 < d2);
assert_eq("1.5", true, d1 >= d2);
assert_eq("1.6", false, d1 > d2);
// Date1 < Date2 VASSERT_EQ(oss.str(), pairs[i].result, d);
vmime::datetime d3(2005, 4, 22, 14, 6, 0);
vmime::datetime d4(2005, 4, 22, 15, 6, 0);
assert_eq("2.1", false, d3 == d4);
assert_eq("2.2", true, d3 != d4);
assert_eq("2.3", true, d3 <= d4);
assert_eq("2.4", true, d3 < d4);
assert_eq("2.5", false, d3 >= d4);
assert_eq("2.6", false, d3 > d4);
// Date1 > Date2
vmime::datetime d5(2005, 4, 22, 15, 6, 0);
vmime::datetime d6(2005, 4, 22, 14, 6, 0);
assert_eq("3.1", false, d5 == d6);
assert_eq("3.2", true, d5 != d6);
assert_eq("3.3", false, d5 <= d6);
assert_eq("3.4", false, d5 < d6);
assert_eq("3.5", true, d5 >= d6);
assert_eq("3.6", true, d5 > d6);
} }
}
public: void testGenerate()
{
vmime::datetime d1(2005, 7, 8, 4, 5, 6, 1 * 60 + 23);
datetimeTest() : suite("vmime::datetime") VASSERT_EQ("1", "Fri, 8 Jul 2005 04:05:06 +0123", d1.generate());
{ }
// VMime initialization
vmime::platformDependant::setHandler<vmime::platforms::posix::posixHandler>();
add("Parse", testcase(this, "Parse", &datetimeTest::testParse)); void testCompare()
add("Generate", testcase(this, "Generate", &datetimeTest::testGenerate)); {
add("Compare", testcase(this, "Compare", &datetimeTest::testCompare)); // Date1 = Date2
vmime::datetime d1(2005, 4, 22, 14, 6, 0, vmime::datetime::GMT2);
vmime::datetime d2(2005, 4, 22, 10, 6, 0, vmime::datetime::GMT_2);
suite::main().add("vmime::datetime", this); VASSERT_EQ("1.1", true, d1 == d2);
} VASSERT_EQ("1.2", false, d1 != d2);
VASSERT_EQ("1.3", true, d1 <= d2);
VASSERT_EQ("1.4", false, d1 < d2);
VASSERT_EQ("1.5", true, d1 >= d2);
VASSERT_EQ("1.6", false, d1 > d2);
}; // Date1 < Date2
vmime::datetime d3(2005, 4, 22, 14, 6, 0);
vmime::datetime d4(2005, 4, 22, 15, 6, 0);
VASSERT_EQ("2.1", false, d3 == d4);
VASSERT_EQ("2.2", true, d3 != d4);
VASSERT_EQ("2.3", true, d3 <= d4);
VASSERT_EQ("2.4", true, d3 < d4);
VASSERT_EQ("2.5", false, d3 >= d4);
VASSERT_EQ("2.6", false, d3 > d4);
// Date1 > Date2
vmime::datetime d5(2005, 4, 22, 15, 6, 0);
vmime::datetime d6(2005, 4, 22, 14, 6, 0);
VASSERT_EQ("3.1", false, d5 == d6);
VASSERT_EQ("3.2", true, d5 != d6);
VASSERT_EQ("3.3", false, d5 <= d6);
VASSERT_EQ("3.4", false, d5 < d6);
VASSERT_EQ("3.5", true, d5 >= d6);
VASSERT_EQ("3.6", true, d5 > d6);
}
VMIME_TEST_SUITE_END
datetimeTest* theTest = new datetimeTest();
}

View File

@ -17,152 +17,135 @@
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
// //
#include "../lib/unit++/unit++.h" #include "tests/testUtils.hpp"
#include <iostream>
#include <ostream>
#include "vmime/vmime.hpp"
#include "vmime/platforms/posix/posixHandler.hpp"
#include "tests/parser/testUtils.hpp"
using namespace unitpp;
namespace #define VMIME_TEST_SUITE dispositionTest
{ #define VMIME_TEST_SUITE_MODULE "Parser"
class dispositionTest : public suite
VMIME_TEST_SUITE_BEGIN
VMIME_TEST_LIST_BEGIN
VMIME_TEST(testParse)
VMIME_TEST(testGenerate)
VMIME_TEST(testModifiers)
VMIME_TEST_LIST_END
void testParse()
{ {
void testParse() // disposition-mode ";" disposition-type
{ // [ "/" disposition-modifier *( "," disposition-modifier ) ]
// disposition-mode ";" disposition-type //
// [ "/" disposition-modifier *( "," disposition-modifier ) ] // disposition-mode = action-mode "/" sending-mode
//
// disposition-mode = action-mode "/" sending-mode
vmime::disposition disp1; vmime::disposition disp1;
disp1.parse("mode"); disp1.parse("mode");
assert_eq("1.1", "mode", disp1.getActionMode()); VASSERT_EQ("1.1", "mode", disp1.getActionMode());
assert_eq("1.2", "", disp1.getSendingMode()); VASSERT_EQ("1.2", "", disp1.getSendingMode());
assert_eq("1.3", "", disp1.getType()); VASSERT_EQ("1.3", "", disp1.getType());
assert_eq("1.4", 0, static_cast <int>(disp1.getModifierList().size())); VASSERT_EQ("1.4", 0, static_cast <int>(disp1.getModifierList().size()));
vmime::disposition disp2; vmime::disposition disp2;
disp2.parse("amode/smode"); disp2.parse("amode/smode");
assert_eq("2.1", "amode", disp2.getActionMode()); VASSERT_EQ("2.1", "amode", disp2.getActionMode());
assert_eq("2.2", "smode", disp2.getSendingMode()); VASSERT_EQ("2.2", "smode", disp2.getSendingMode());
assert_eq("2.3", "", disp2.getType()); VASSERT_EQ("2.3", "", disp2.getType());
assert_eq("2.4", 0, static_cast <int>(disp2.getModifierList().size())); VASSERT_EQ("2.4", 0, static_cast <int>(disp2.getModifierList().size()));
vmime::disposition disp3; vmime::disposition disp3;
disp3.parse("amode/smode;type"); disp3.parse("amode/smode;type");
assert_eq("3.1", "amode", disp3.getActionMode()); VASSERT_EQ("3.1", "amode", disp3.getActionMode());
assert_eq("3.2", "smode", disp3.getSendingMode()); VASSERT_EQ("3.2", "smode", disp3.getSendingMode());
assert_eq("3.3", "type", disp3.getType()); VASSERT_EQ("3.3", "type", disp3.getType());
assert_eq("3.4", 0, static_cast <int>(disp3.getModifierList().size())); VASSERT_EQ("3.4", 0, static_cast <int>(disp3.getModifierList().size()));
vmime::disposition disp4; vmime::disposition disp4;
disp4.parse("amode/smode;type/modif"); disp4.parse("amode/smode;type/modif");
assert_eq("4.1", "amode", disp4.getActionMode()); VASSERT_EQ("4.1", "amode", disp4.getActionMode());
assert_eq("4.2", "smode", disp4.getSendingMode()); VASSERT_EQ("4.2", "smode", disp4.getSendingMode());
assert_eq("4.3", "type", disp4.getType()); VASSERT_EQ("4.3", "type", disp4.getType());
assert_eq("4.4", 1, static_cast <int>(disp4.getModifierList().size())); VASSERT_EQ("4.4", 1, static_cast <int>(disp4.getModifierList().size()));
assert_eq("4.5", "modif", disp4.getModifierList()[0]); VASSERT_EQ("4.5", "modif", disp4.getModifierList()[0]);
vmime::disposition disp5; vmime::disposition disp5;
disp5.parse("amode/smode;type/modif1,modif2"); disp5.parse("amode/smode;type/modif1,modif2");
assert_eq("5.1", "amode", disp5.getActionMode()); VASSERT_EQ("5.1", "amode", disp5.getActionMode());
assert_eq("5.2", "smode", disp5.getSendingMode()); VASSERT_EQ("5.2", "smode", disp5.getSendingMode());
assert_eq("5.3", "type", disp5.getType()); VASSERT_EQ("5.3", "type", disp5.getType());
assert_eq("5.4", 2, static_cast <int>(disp5.getModifierList().size())); VASSERT_EQ("5.4", 2, static_cast <int>(disp5.getModifierList().size()));
assert_eq("5.5", "modif1", disp5.getModifierList()[0]); VASSERT_EQ("5.5", "modif1", disp5.getModifierList()[0]);
assert_eq("5.6", "modif2", disp5.getModifierList()[1]); VASSERT_EQ("5.6", "modif2", disp5.getModifierList()[1]);
} }
void testGenerate() void testGenerate()
{ {
vmime::disposition disp; vmime::disposition disp;
assert_eq("1", "automatic-action/MDN-sent-automatically;displayed", disp.generate()); VASSERT_EQ("1", "automatic-action/MDN-sent-automatically;displayed", disp.generate());
disp.setActionMode("amode"); disp.setActionMode("amode");
assert_eq("2", "amode/MDN-sent-automatically;displayed", disp.generate()); VASSERT_EQ("2", "amode/MDN-sent-automatically;displayed", disp.generate());
disp.setActionMode("amode"); disp.setActionMode("amode");
disp.setSendingMode("smode"); disp.setSendingMode("smode");
assert_eq("3", "amode/smode;displayed", disp.generate()); VASSERT_EQ("3", "amode/smode;displayed", disp.generate());
disp.setType("type"); disp.setType("type");
assert_eq("4", "amode/smode;type", disp.generate()); VASSERT_EQ("4", "amode/smode;type", disp.generate());
disp.addModifier("modif1"); disp.addModifier("modif1");
assert_eq("5", "amode/smode;type/modif1", disp.generate()); VASSERT_EQ("5", "amode/smode;type/modif1", disp.generate());
disp.addModifier("modif2"); disp.addModifier("modif2");
assert_eq("6", "amode/smode;type/modif1,modif2", disp.generate()); VASSERT_EQ("6", "amode/smode;type/modif1,modif2", disp.generate());
} }
void testModifiers() void testModifiers()
{ {
vmime::disposition disp1; vmime::disposition disp1;
assert_eq("1", false, disp1.hasModifier("foo")); VASSERT_EQ("1", false, disp1.hasModifier("foo"));
assert_eq("2", 0, static_cast <int>(disp1.getModifierList().size())); VASSERT_EQ("2", 0, static_cast <int>(disp1.getModifierList().size()));
disp1.addModifier("bar"); disp1.addModifier("bar");
assert_eq("3", false, disp1.hasModifier("foo")); VASSERT_EQ("3", false, disp1.hasModifier("foo"));
assert_eq("4", true, disp1.hasModifier("bar")); VASSERT_EQ("4", true, disp1.hasModifier("bar"));
assert_eq("5", 1, static_cast <int>(disp1.getModifierList().size())); VASSERT_EQ("5", 1, static_cast <int>(disp1.getModifierList().size()));
disp1.addModifier("plop"); disp1.addModifier("plop");
assert_eq("6", false, disp1.hasModifier("foo")); VASSERT_EQ("6", false, disp1.hasModifier("foo"));
assert_eq("7", true, disp1.hasModifier("bar")); VASSERT_EQ("7", true, disp1.hasModifier("bar"));
assert_eq("8", true, disp1.hasModifier("plop")); VASSERT_EQ("8", true, disp1.hasModifier("plop"));
assert_eq("9", 2, static_cast <int>(disp1.getModifierList().size())); VASSERT_EQ("9", 2, static_cast <int>(disp1.getModifierList().size()));
disp1.removeModifier("bar"); disp1.removeModifier("bar");
assert_eq("10", false, disp1.hasModifier("foo")); VASSERT_EQ("10", false, disp1.hasModifier("foo"));
assert_eq("11", false, disp1.hasModifier("bar")); VASSERT_EQ("11", false, disp1.hasModifier("bar"));
assert_eq("12", true, disp1.hasModifier("plop")); VASSERT_EQ("12", true, disp1.hasModifier("plop"));
assert_eq("13", 1, static_cast <int>(disp1.getModifierList().size())); VASSERT_EQ("13", 1, static_cast <int>(disp1.getModifierList().size()));
disp1.removeModifier("PlOp"); disp1.removeModifier("PlOp");
assert_eq("14", false, disp1.hasModifier("foo")); VASSERT_EQ("14", false, disp1.hasModifier("foo"));
assert_eq("15", false, disp1.hasModifier("bar")); VASSERT_EQ("15", false, disp1.hasModifier("bar"));
assert_eq("16", false, disp1.hasModifier("plop")); VASSERT_EQ("16", false, disp1.hasModifier("plop"));
assert_eq("17", 0, static_cast <int>(disp1.getModifierList().size())); VASSERT_EQ("17", 0, static_cast <int>(disp1.getModifierList().size()));
} }
public: VMIME_TEST_SUITE_END
dispositionTest() : suite("vmime::disposition")
{
vmime::platformDependant::setHandler<vmime::platforms::posix::posixHandler>();
add("Parse", testcase(this, "Parse", &dispositionTest::testParse));
add("Generate", testcase(this, "Generate", &dispositionTest::testGenerate));
add("Modifiers", testcase(this, "Modifiers", &dispositionTest::testModifiers));
suite::main().add("vmime::disposition", this);
}
};
dispositionTest* theTest = new dispositionTest();
}

View File

@ -17,282 +17,268 @@
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
// //
#include "../lib/unit++/unit++.h" #include "tests/testUtils.hpp"
#include <iostream>
#include <ostream>
#include "vmime/vmime.hpp"
#include "vmime/platforms/posix/posixHandler.hpp"
using namespace unitpp;
namespace #define VMIME_TEST_SUITE encoderTest
{ #define VMIME_TEST_SUITE_MODULE "Parser"
class encoderTest : public suite
VMIME_TEST_SUITE_BEGIN
VMIME_TEST_LIST_BEGIN
VMIME_TEST(testBase64)
VMIME_TEST(testQuotedPrintable)
VMIME_TEST_LIST_END
// Encoding helper function
static const vmime::string encode(const vmime::string& name, const vmime::string& in, int maxLineLength = 0)
{ {
// Encoding helper function vmime::ref <vmime::encoder> enc = vmime::encoderFactory::getInstance()->create(name);
static const vmime::string encode(const vmime::string& name, const vmime::string& in, int maxLineLength = 0)
if (maxLineLength != 0)
enc->getProperties()["maxlinelength"] = maxLineLength;
vmime::utility::inputStreamStringAdapter vin(in);
std::ostringstream out;
vmime::utility::outputStreamAdapter vout(out);
enc->encode(vin, vout);
return (out.str());
}
// Decoding helper function
static const vmime::string decode(const vmime::string& name, const vmime::string& in, int maxLineLength = 0)
{
vmime::ref <vmime::encoder> enc = vmime::encoderFactory::getInstance()->create(name);
if (maxLineLength != 0)
enc->getProperties()["maxlinelength"] = maxLineLength;
vmime::utility::inputStreamStringAdapter vin(in);
std::ostringstream out;
vmime::utility::outputStreamAdapter vout(out);
enc->decode(vin, vout);
return (out.str());
}
void testBase64()
{
static const vmime::string testSuites[] =
{ {
vmime::ref <vmime::encoder> enc = vmime::encoderFactory::getInstance()->create(name); // Test 1
"",
if (maxLineLength != 0) "",
enc->getProperties()["maxlinelength"] = maxLineLength;
vmime::utility::inputStreamStringAdapter vin(in); // Test 2
"A",
std::ostringstream out; "QQ==",
vmime::utility::outputStreamAdapter vout(out);
enc->encode(vin, vout); // Test 3
"AB",
return (out.str()); "QUI=",
}
// Decoding helper function // Test 4
static const vmime::string decode(const vmime::string& name, const vmime::string& in, int maxLineLength = 0) "ABC",
"QUJD",
// Test 5
"foo",
"Zm9v",
// Test 6
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
"QUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVphYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ejAx"
"MjM0NTY3ODk=",
// Test 7
vmime::string(
"\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
"\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f"
"\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f"
"\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f"
"\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f"
"\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f"
"\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f"
"\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f"
"\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f"
"\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f"
"\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf"
"\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf"
"\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf"
"\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf"
"\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef"
"\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff",
256),
"AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMDEyMzQ1"
"Njc4OTo7PD0+P0BBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWltcXV5fYGFiY2RlZmdoaWpr"
"bG1ub3BxcnN0dXZ3eHl6e3x9fn+AgYKDhIWGh4iJiouMjY6PkJGSk5SVlpeYmZqbnJ2en6Ch"
"oqOkpaanqKmqq6ytrq+wsbKztLW2t7i5uru8vb6/wMHCw8TFxsfIycrLzM3Oz9DR0tPU1dbX"
"2Nna29zd3t/g4eLj5OXm5+jp6uvs7e7v8PHy8/T19vf4+fr7/P3+/w=="
};
for (unsigned int i = 0 ; i < sizeof(testSuites) / sizeof(testSuites[0]) / 2 ; ++i)
{ {
vmime::ref <vmime::encoder> enc = vmime::encoderFactory::getInstance()->create(name); const vmime::string decoded = testSuites[i * 2];
const vmime::string encoded = testSuites[i * 2 + 1];
if (maxLineLength != 0) std::ostringstream oss;
enc->getProperties()["maxlinelength"] = maxLineLength; oss << "[Base64] Test " << (i + 1) << ": ";
vmime::utility::inputStreamStringAdapter vin(in); // Encoding
VASSERT_EQ(oss.str() + "encoding", encoded, encode("base64", decoded));
std::ostringstream out; // Decoding
vmime::utility::outputStreamAdapter vout(out); VASSERT_EQ(oss.str() + "decoding", decoded, decode("base64", encoded));
enc->decode(vin, vout); // Multiple and successive encoding/decoding
VASSERT_EQ(oss.str() + "multiple1", decoded,
decode("base64",
encode("base64", decoded)));
return (out.str()); VASSERT_EQ(oss.str() + "multiple2", decoded,
} decode("base64",
void testBase64()
{
static const vmime::string testSuites[] =
{
// Test 1
"",
"",
// Test 2
"A",
"QQ==",
// Test 3
"AB",
"QUI=",
// Test 4
"ABC",
"QUJD",
// Test 5
"foo",
"Zm9v",
// Test 6
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789",
"QUJDREVGR0hJSktMTU5PUFFSU1RVVldYWVphYmNkZWZnaGlqa2xtbm9wcXJzdHV2d3h5ejAx"
"MjM0NTY3ODk=",
// Test 7
vmime::string(
"\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0a\x0b\x0c\x0d\x0e\x0f"
"\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1a\x1b\x1c\x1d\x1e\x1f"
"\x20\x21\x22\x23\x24\x25\x26\x27\x28\x29\x2a\x2b\x2c\x2d\x2e\x2f"
"\x30\x31\x32\x33\x34\x35\x36\x37\x38\x39\x3a\x3b\x3c\x3d\x3e\x3f"
"\x40\x41\x42\x43\x44\x45\x46\x47\x48\x49\x4a\x4b\x4c\x4d\x4e\x4f"
"\x50\x51\x52\x53\x54\x55\x56\x57\x58\x59\x5a\x5b\x5c\x5d\x5e\x5f"
"\x60\x61\x62\x63\x64\x65\x66\x67\x68\x69\x6a\x6b\x6c\x6d\x6e\x6f"
"\x70\x71\x72\x73\x74\x75\x76\x77\x78\x79\x7a\x7b\x7c\x7d\x7e\x7f"
"\x80\x81\x82\x83\x84\x85\x86\x87\x88\x89\x8a\x8b\x8c\x8d\x8e\x8f"
"\x90\x91\x92\x93\x94\x95\x96\x97\x98\x99\x9a\x9b\x9c\x9d\x9e\x9f"
"\xa0\xa1\xa2\xa3\xa4\xa5\xa6\xa7\xa8\xa9\xaa\xab\xac\xad\xae\xaf"
"\xb0\xb1\xb2\xb3\xb4\xb5\xb6\xb7\xb8\xb9\xba\xbb\xbc\xbd\xbe\xbf"
"\xc0\xc1\xc2\xc3\xc4\xc5\xc6\xc7\xc8\xc9\xca\xcb\xcc\xcd\xce\xcf"
"\xd0\xd1\xd2\xd3\xd4\xd5\xd6\xd7\xd8\xd9\xda\xdb\xdc\xdd\xde\xdf"
"\xe0\xe1\xe2\xe3\xe4\xe5\xe6\xe7\xe8\xe9\xea\xeb\xec\xed\xee\xef"
"\xf0\xf1\xf2\xf3\xf4\xf5\xf6\xf7\xf8\xf9\xfa\xfb\xfc\xfd\xfe\xff",
256),
"AAECAwQFBgcICQoLDA0ODxAREhMUFRYXGBkaGxwdHh8gISIjJCUmJygpKissLS4vMDEyMzQ1"
"Njc4OTo7PD0+P0BBQkNERUZHSElKS0xNTk9QUVJTVFVWV1hZWltcXV5fYGFiY2RlZmdoaWpr"
"bG1ub3BxcnN0dXZ3eHl6e3x9fn+AgYKDhIWGh4iJiouMjY6PkJGSk5SVlpeYmZqbnJ2en6Ch"
"oqOkpaanqKmqq6ytrq+wsbKztLW2t7i5uru8vb6/wMHCw8TFxsfIycrLzM3Oz9DR0tPU1dbX"
"2Nna29zd3t/g4eLj5OXm5+jp6uvs7e7v8PHy8/T19vf4+fr7/P3+/w=="
};
for (unsigned int i = 0 ; i < sizeof(testSuites) / sizeof(testSuites[0]) / 2 ; ++i)
{
const vmime::string decoded = testSuites[i * 2];
const vmime::string encoded = testSuites[i * 2 + 1];
std::ostringstream oss;
oss << "[Base64] Test " << (i + 1) << ": ";
// Encoding
assert_eq(oss.str() + "encoding", encoded, encode("base64", decoded));
// Decoding
assert_eq(oss.str() + "decoding", decoded, decode("base64", encoded));
// Multiple and successive encoding/decoding
assert_eq(oss.str() + "multiple1", decoded,
decode("base64", decode("base64",
encode("base64", decoded))); encode("base64",
encode("base64", decoded)))));
assert_eq(oss.str() + "multiple2", decoded, VASSERT_EQ(oss.str() + "multiple3", decoded,
decode("base64",
decode("base64", decode("base64",
decode("base64", decode("base64",
encode("base64", encode("base64",
encode("base64", decoded))))); encode("base64",
encode("base64", decoded)))))));
assert_eq(oss.str() + "multiple3", decoded, VASSERT_EQ(oss.str() + "multiple4", decoded,
decode("base64",
decode("base64", decode("base64",
decode("base64", decode("base64",
decode("base64", decode("base64",
encode("base64", encode("base64",
encode("base64",
encode("base64", decoded)))))));
assert_eq(oss.str() + "multiple4", decoded,
decode("base64",
decode("base64",
decode("base64",
decode("base64",
encode("base64", encode("base64",
encode("base64", encode("base64",
encode("base64", encode("base64", decoded)))))))));
encode("base64", decoded)))))))));
}
} }
}
void testQuotedPrintable() void testQuotedPrintable()
{
static const vmime::string testSuites[] =
{ {
static const vmime::string testSuites[] = // Test 1
{ "",
// Test 1
"",
"", "",
// Test 2 // Test 2
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ", "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ",
"abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ", "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ",
// Test 3 // Test 3
"0123456789012345678901234567890123456789012345678901234567890123456789012" "0123456789012345678901234567890123456789012345678901234567890123456789012"
"3456789012345678901234567890123456789012345678901234567890123456789012345" "3456789012345678901234567890123456789012345678901234567890123456789012345"
"6789", "6789",
"0123456789012345678901234567890123456789012345678901234567890123456789012=\r\n" "0123456789012345678901234567890123456789012345678901234567890123456789012=\r\n"
"3456789012345678901234567890123456789012345678901234567890123456789012345=\r\n" "3456789012345678901234567890123456789012345678901234567890123456789012345=\r\n"
"6789", "6789",
// Test 4 // Test 4
vmime::string( vmime::string(
"\x89\xe8\x24\x04\x2f\xe8\xff\xfb\xeb\xff\x90\xd7\x74\x8d\x00\x26\x89\x55" "\x89\xe8\x24\x04\x2f\xe8\xff\xfb\xeb\xff\x90\xd7\x74\x8d\x00\x26\x89\x55"
"\x83\xe5\x08\xec\x04\xc7\xa0\x24\x05\xa2\xe8\x08\x43\xee\x00\x00\xc0\x85" "\x83\xe5\x08\xec\x04\xc7\xa0\x24\x05\xa2\xe8\x08\x43\xee\x00\x00\xc0\x85"
"\x0a\x74\xec\x89\xc3\x5d\xb6\x8d\x00\x00\x00\x00\x04\xc7\xa8\x24\x05\xa2" "\x0a\x74\xec\x89\xc3\x5d\xb6\x8d\x00\x00\x00\x00\x04\xc7\xa8\x24\x05\xa2"
"\xe8\x08\x43\xd4\x00\x00\xe8\xeb\xf6\x89\x89\x55\x81\xe5\xa8\xec\x00\x00" "\xe8\x08\x43\xd4\x00\x00\xe8\xeb\xf6\x89\x89\x55\x81\xe5\xa8\xec\x00\x00"
"\x89\x00\xfc\x75\x75\x8b\x89\x08\xf8\x5d\xb9\xe8\xff\xff\x83\xff\x14\xfe" "\x89\x00\xfc\x75\x75\x8b\x89\x08\xf8\x5d\xb9\xe8\xff\xff\x83\xff\x14\xfe"
"\x47\x74\xc0\x31\x9d\x8d\xff\x68\xff\xff\x85\x89\xff\x68\xff\xff\x85\x8d" "\x47\x74\xc0\x31\x9d\x8d\xff\x68\xff\xff\x85\x89\xff\x68\xff\xff\x85\x8d"
"\xff\x6c\xff\xff\x04\x89\xe8\x24\xfa\x50\xff\xff\x45\xc7\x00\xec\x00\x00" "\xff\x6c\xff\xff\x04\x89\xe8\x24\xfa\x50\xff\xff\x45\xc7\x00\xec\x00\x00"
"\x31\x00\x89\xc0\x24\x44\x89\x08\x24\x5c\x89\x04\x24\x34\x87\xe8\xff\xf6" "\x31\x00\x89\xc0\x24\x44\x89\x08\x24\x5c\x89\x04\x24\x34\x87\xe8\xff\xf6"
"\x89\xff\x24\x34\x2f\xe8\xff\xf9\x8b\xff\xf8\x5d\x75\x8b\x89\xfc\x5d\xec" "\x89\xff\x24\x34\x2f\xe8\xff\xf9\x8b\xff\xf8\x5d\x75\x8b\x89\xfc\x5d\xec"
"\xbe\xc3\x00\x13\x00\x00\xe7\xeb\xb6\x8d\x00\x00\x00\x00\x89\x55\x57\xe5" "\xbe\xc3\x00\x13\x00\x00\xe7\xeb\xb6\x8d\x00\x00\x00\x00\x89\x55\x57\xe5"
"\x53\x56\xec\x81\x01\xdc\x00\x00\x45\xbb\x05\x5c\x8b\x08\x0c\x55\xe4\x83" "\x53\x56\xec\x81\x01\xdc\x00\x00\x45\xbb\x05\x5c\x8b\x08\x0c\x55\xe4\x83"
"\x8b\xf0\x89\x02\x24\x5c\xc7\x04\x24\x04\x00\x06\x00\x00\xec\xa3\x05\xa9" "\x8b\xf0\x89\x02\x24\x5c\xc7\x04\x24\x04\x00\x06\x00\x00\xec\xa3\x05\xa9"
"\xe8\x08\xf7\x2a\xff\xff\x04\xc7\x46\x24\x05\x5c\xb9\x08\x5c\x50\x08\x05" "\xe8\x08\xf7\x2a\xff\xff\x04\xc7\x46\x24\x05\x5c\xb9\x08\x5c\x50\x08\x05"
"\x4c\x89\x04\x24\xf5\xe8\xff\xf7\xc7\xff\x24\x04\x5c\x46\x08\x05\xe9\xe8" "\x4c\x89\x04\x24\xf5\xe8\xff\xf7\xc7\xff\x24\x04\x5c\x46\x08\x05\xe9\xe8"
"\xff\xf8\xc7\xff\x24\x04\x1d\x70\x08\x05\x55\xe8\x00\xbb\xb8\x00\x00\x01" "\xff\xf8\xc7\xff\x24\x04\x1d\x70\x08\x05\x55\xe8\x00\xbb\xb8\x00\x00\x01"
"\x00\x00\xd2\x31\x08\xa3\x05\xa7\xb8\x08\x00\x01\x00\x00\x0c\xa3\x05\xa7", "\x00\x00\xd2\x31\x08\xa3\x05\xa7\xb8\x08\x00\x01\x00\x00\x0c\xa3\x05\xa7",
18 * 16), 18 * 16),
"=89=E8$=04/=E8=FF=FB=EB=FF=90=D7t=8D=00&=89U=83=E5=08=EC=04=C7=A0$=05=A2=E8=\r\n" "=89=E8$=04/=E8=FF=FB=EB=FF=90=D7t=8D=00&=89U=83=E5=08=EC=04=C7=A0$=05=A2=E8=\r\n"
"=08C=EE=00=00=C0=85=0At=EC=89=C3]=B6=8D=00=00=00=00=04=C7=A8$=05=A2=E8=08=\r\n" "=08C=EE=00=00=C0=85=0At=EC=89=C3]=B6=8D=00=00=00=00=04=C7=A8$=05=A2=E8=08=\r\n"
"C=D4=00=00=E8=EB=F6=89=89U=81=E5=A8=EC=00=00=89=00=FCuu=8B=89=08=F8]=B9=E8=\r\n" "C=D4=00=00=E8=EB=F6=89=89U=81=E5=A8=EC=00=00=89=00=FCuu=8B=89=08=F8]=B9=E8=\r\n"
"=FF=FF=83=FF=14=FEGt=C01=9D=8D=FFh=FF=FF=85=89=FFh=FF=FF=85=8D=FFl=FF=FF=04=\r\n" "=FF=FF=83=FF=14=FEGt=C01=9D=8D=FFh=FF=FF=85=89=FFh=FF=FF=85=8D=FFl=FF=FF=04=\r\n"
"=89=E8$=FAP=FF=FFE=C7=00=EC=00=001=00=89=C0$D=89=08$\\=89=04$4=87=E8=FF=F6=\r\n" "=89=E8$=FAP=FF=FFE=C7=00=EC=00=001=00=89=C0$D=89=08$\\=89=04$4=87=E8=FF=F6=\r\n"
"=89=FF$4/=E8=FF=F9=8B=FF=F8]u=8B=89=FC]=EC=BE=C3=00=13=00=00=E7=EB=B6=8D=00=\r\n" "=89=FF$4/=E8=FF=F9=8B=FF=F8]u=8B=89=FC]=EC=BE=C3=00=13=00=00=E7=EB=B6=8D=00=\r\n"
"=00=00=00=89UW=E5SV=EC=81=01=DC=00=00E=BB=05\\=8B=08=0CU=E4=83=8B=F0=89=02=\r\n" "=00=00=00=89UW=E5SV=EC=81=01=DC=00=00E=BB=05\\=8B=08=0CU=E4=83=8B=F0=89=02=\r\n"
"$\\=C7=04$=04=00=06=00=00=EC=A3=05=A9=E8=08=F7*=FF=FF=04=C7F$=05\\=B9=08\\P=08=\r\n" "$\\=C7=04$=04=00=06=00=00=EC=A3=05=A9=E8=08=F7*=FF=FF=04=C7F$=05\\=B9=08\\P=08=\r\n"
"=05L=89=04$=F5=E8=FF=F7=C7=FF$=04\\F=08=05=E9=E8=FF=F8=C7=FF$=04=1Dp=08=05=\r\n" "=05L=89=04$=F5=E8=FF=F7=C7=FF$=04\\F=08=05=E9=E8=FF=F8=C7=FF$=04=1Dp=08=05=\r\n"
"U=E8=00=BB=B8=00=00=01=00=00=D21=08=A3=05=A7=B8=08=00=01=00=00=0C=A3=05=A7=\r\n" "U=E8=00=BB=B8=00=00=01=00=00=D21=08=A3=05=A7=B8=08=00=01=00=00=0C=A3=05=A7=\r\n"
}; };
for (unsigned int i = 0 ; i < sizeof(testSuites) / sizeof(testSuites[0]) / 2 ; ++i) for (unsigned int i = 0 ; i < sizeof(testSuites) / sizeof(testSuites[0]) / 2 ; ++i)
{ {
const vmime::string decoded = testSuites[i * 2]; const vmime::string decoded = testSuites[i * 2];
const vmime::string encoded = testSuites[i * 2 + 1]; const vmime::string encoded = testSuites[i * 2 + 1];
std::ostringstream oss; std::ostringstream oss;
oss << "[QP] Test " << (i + 1) << ": "; oss << "[QP] Test " << (i + 1) << ": ";
// Encoding // Encoding
assert_eq(oss.str() + "encoding", encoded, encode("quoted-printable", decoded, 74)); VASSERT_EQ(oss.str() + "encoding", encoded, encode("quoted-printable", decoded, 74));
// Decoding // Decoding
assert_eq(oss.str() + "decoding", decoded, decode("quoted-printable", encoded, 74)); VASSERT_EQ(oss.str() + "decoding", decoded, decode("quoted-printable", encoded, 74));
// Multiple and successive encoding/decoding // Multiple and successive encoding/decoding
assert_eq(oss.str() + "multiple1", decoded, VASSERT_EQ(oss.str() + "multiple1", decoded,
decode("quoted-printable",
encode("quoted-printable", decoded)));
VASSERT_EQ(oss.str() + "multiple2", decoded,
decode("quoted-printable",
decode("quoted-printable", decode("quoted-printable",
encode("quoted-printable", decoded))); encode("quoted-printable",
encode("quoted-printable", decoded)))));
assert_eq(oss.str() + "multiple2", decoded, VASSERT_EQ(oss.str() + "multiple3", decoded,
decode("quoted-printable",
decode("quoted-printable", decode("quoted-printable",
decode("quoted-printable", decode("quoted-printable",
encode("quoted-printable", encode("quoted-printable",
encode("quoted-printable", decoded))))); encode("quoted-printable",
encode("quoted-printable", decoded)))))));
assert_eq(oss.str() + "multiple3", decoded, VASSERT_EQ(oss.str() + "multiple4", decoded,
decode("quoted-printable",
decode("quoted-printable", decode("quoted-printable",
decode("quoted-printable", decode("quoted-printable",
decode("quoted-printable", decode("quoted-printable",
encode("quoted-printable", encode("quoted-printable",
encode("quoted-printable",
encode("quoted-printable", decoded)))))));
assert_eq(oss.str() + "multiple4", decoded,
decode("quoted-printable",
decode("quoted-printable",
decode("quoted-printable",
decode("quoted-printable",
encode("quoted-printable", encode("quoted-printable",
encode("quoted-printable", encode("quoted-printable",
encode("quoted-printable", encode("quoted-printable", decoded)))))))));
encode("quoted-printable", decoded)))))))));
}
} }
}
// TODO: UUEncode // TODO: UUEncode
public: VMIME_TEST_SUITE_END
encoderTest() : suite("vmime::encoder")
{
vmime::platformDependant::setHandler<vmime::platforms::posix::posixHandler>();
add("Base64", testcase(this, "Base64", &encoderTest::testBase64));
add("QuotedPrintable", testcase(this, "QuotedPrintable", &encoderTest::testQuotedPrintable));
suite::main().add("vmime::encoder", this);
}
};
encoderTest* theTest = new encoderTest();
}

View File

@ -17,356 +17,341 @@
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
// //
#include "../lib/unit++/unit++.h" #include "tests/testUtils.hpp"
#include <iostream>
#include <ostream>
#include "vmime/vmime.hpp"
#include "vmime/platforms/posix/posixHandler.hpp"
using namespace unitpp;
namespace #define VMIME_TEST_SUITE headerTest
{ #define VMIME_TEST_SUITE_MODULE "Parser"
class headerTest : public suite
VMIME_TEST_SUITE_BEGIN
VMIME_TEST_LIST_BEGIN
VMIME_TEST(testHas1)
VMIME_TEST(testHas2)
VMIME_TEST(testAppend1)
VMIME_TEST(testAppend2)
VMIME_TEST(testInsertFieldBefore1)
VMIME_TEST(testInsertFieldBefore2)
VMIME_TEST(testInsertFieldAfter1)
VMIME_TEST(testInsertFieldAfter2)
VMIME_TEST(testRemoveField1)
VMIME_TEST(testRemoveField2)
VMIME_TEST(testRemoveAllFields)
VMIME_TEST(testgetFieldCount)
VMIME_TEST(testIsEmpty1)
VMIME_TEST(testIsEmpty2)
VMIME_TEST(testGetFieldAt)
VMIME_TEST(testGetFieldList1)
VMIME_TEST(testGetFieldList2)
VMIME_TEST(testFind1)
VMIME_TEST(testFindAllFields1)
VMIME_TEST(testFindAllFields2)
VMIME_TEST(testFindAllFields3)
VMIME_TEST_LIST_END
static const std::string getFieldValue(const vmime::headerField& field)
{ {
static const std::string getFieldValue(const vmime::headerField& field) std::ostringstream oss;
{ vmime::utility::outputStreamAdapter voss(oss);
std::ostringstream oss; field.generate(voss);
vmime::utility::outputStreamAdapter voss(oss);
field.generate(voss);
return (oss.str()); return (oss.str());
} }
// has function tests // has function tests
void testHas1() void testHas1()
{ {
vmime::header hdr; vmime::header hdr;
hdr.parse("From: x\r\nTo: y\r\nTo: z\r\n"); hdr.parse("From: x\r\nTo: y\r\nTo: z\r\n");
bool res = hdr.hasField("Z"); bool res = hdr.hasField("Z");
assert_eq("Value", false, res); VASSERT_EQ("Value", false, res);
} }
void testHas2() void testHas2()
{ {
vmime::header hdr; vmime::header hdr;
hdr.parse("X: x\r\nTo: y\r\nTo: z\r\n"); hdr.parse("X: x\r\nTo: y\r\nTo: z\r\n");
bool res = hdr.hasField("To"); bool res = hdr.hasField("To");
assert_eq("Value", true, res); VASSERT_EQ("Value", true, res);
} }
// appendField function tests // appendField function tests
void testAppend1() void testAppend1()
{ {
vmime::header hdr; vmime::header hdr;
hdr.parse(""); hdr.parse("");
vmime::ref <vmime::headerField> hf = vmime::headerFieldFactory::getInstance()->create("A", "a"); vmime::ref <vmime::headerField> hf = vmime::headerFieldFactory::getInstance()->create("A", "a");
hdr.appendField(hf); hdr.appendField(hf);
std::vector <vmime::ref <vmime::headerField> > res = hdr.getFieldList(); std::vector <vmime::ref <vmime::headerField> > res = hdr.getFieldList();
assert_eq("Count", static_cast <unsigned int>(1), res.size()); VASSERT_EQ("Count", static_cast <unsigned int>(1), res.size());
assert_eq("First value", "A: a", headerTest::getFieldValue(*res[0])); VASSERT_EQ("First value", "A: a", headerTest::getFieldValue(*res[0]));
} }
void testAppend2() void testAppend2()
{ {
vmime::header hdr; vmime::header hdr;
hdr.parse("A: a\r\n"); hdr.parse("A: a\r\n");
vmime::ref <vmime::headerField> hf = vmime::headerFieldFactory::getInstance()->create("B", "b"); vmime::ref <vmime::headerField> hf = vmime::headerFieldFactory::getInstance()->create("B", "b");
hdr.appendField(hf); hdr.appendField(hf);
std::vector <vmime::ref <vmime::headerField> > res = hdr.getFieldList(); std::vector <vmime::ref <vmime::headerField> > res = hdr.getFieldList();
assert_eq("Count", static_cast <unsigned int>(2), res.size()); VASSERT_EQ("Count", static_cast <unsigned int>(2), res.size());
assert_eq("First value", "A: a", headerTest::getFieldValue(*res[0])); VASSERT_EQ("First value", "A: a", headerTest::getFieldValue(*res[0]));
assert_eq("Second value", "B: b", headerTest::getFieldValue(*res[1])); VASSERT_EQ("Second value", "B: b", headerTest::getFieldValue(*res[1]));
} }
// insertFieldBefore // insertFieldBefore
void testInsertFieldBefore1() void testInsertFieldBefore1()
{ {
vmime::header hdr; vmime::header hdr;
hdr.parse("A: a\r\nC: c\r\n"); hdr.parse("A: a\r\nC: c\r\n");
vmime::ref <vmime::headerField> hf = vmime::headerFieldFactory::getInstance()->create("B", "b"); vmime::ref <vmime::headerField> hf = vmime::headerFieldFactory::getInstance()->create("B", "b");
hdr.insertFieldBefore(hdr.getField("C"), hf); hdr.insertFieldBefore(hdr.getField("C"), hf);
std::vector <vmime::ref <vmime::headerField> > res = hdr.getFieldList(); std::vector <vmime::ref <vmime::headerField> > res = hdr.getFieldList();
assert_eq("Count", static_cast <unsigned int>(3), res.size()); VASSERT_EQ("Count", static_cast <unsigned int>(3), res.size());
assert_eq("First value", "A: a", headerTest::getFieldValue(*res[0])); VASSERT_EQ("First value", "A: a", headerTest::getFieldValue(*res[0]));
assert_eq("Second value", "B: b", headerTest::getFieldValue(*res[1])); VASSERT_EQ("Second value", "B: b", headerTest::getFieldValue(*res[1]));
assert_eq("Third value", "C: c", headerTest::getFieldValue(*res[2])); VASSERT_EQ("Third value", "C: c", headerTest::getFieldValue(*res[2]));
} }
void testInsertFieldBefore2() void testInsertFieldBefore2()
{ {
vmime::header hdr; vmime::header hdr;
hdr.parse("A: a\r\nC: c\r\n"); hdr.parse("A: a\r\nC: c\r\n");
vmime::ref <vmime::headerField> hf = vmime::headerFieldFactory::getInstance()->create("B", "b"); vmime::ref <vmime::headerField> hf = vmime::headerFieldFactory::getInstance()->create("B", "b");
hdr.insertFieldBefore(1, hf); hdr.insertFieldBefore(1, hf);
std::vector <vmime::ref <vmime::headerField> > res = hdr.getFieldList(); std::vector <vmime::ref <vmime::headerField> > res = hdr.getFieldList();
assert_eq("Count", static_cast <unsigned int>(3), res.size()); VASSERT_EQ("Count", static_cast <unsigned int>(3), res.size());
assert_eq("First value", "A: a", headerTest::getFieldValue(*res[0])); VASSERT_EQ("First value", "A: a", headerTest::getFieldValue(*res[0]));
assert_eq("Second value", "B: b", headerTest::getFieldValue(*res[1])); VASSERT_EQ("Second value", "B: b", headerTest::getFieldValue(*res[1]));
assert_eq("Third value", "C: c", headerTest::getFieldValue(*res[2])); VASSERT_EQ("Third value", "C: c", headerTest::getFieldValue(*res[2]));
} }
// insertFieldAfter // insertFieldAfter
void testInsertFieldAfter1() void testInsertFieldAfter1()
{ {
vmime::header hdr; vmime::header hdr;
hdr.parse("A: a\r\nC: c\r\n"); hdr.parse("A: a\r\nC: c\r\n");
vmime::ref <vmime::headerField> hf = vmime::headerFieldFactory::getInstance()->create("B", "b"); vmime::ref <vmime::headerField> hf = vmime::headerFieldFactory::getInstance()->create("B", "b");
hdr.insertFieldAfter(hdr.getField("A"), hf); hdr.insertFieldAfter(hdr.getField("A"), hf);
std::vector <vmime::ref <vmime::headerField> > res = hdr.getFieldList(); std::vector <vmime::ref <vmime::headerField> > res = hdr.getFieldList();
assert_eq("Count", static_cast <unsigned int>(3), res.size()); VASSERT_EQ("Count", static_cast <unsigned int>(3), res.size());
assert_eq("First value", "A: a", headerTest::getFieldValue(*res[0])); VASSERT_EQ("First value", "A: a", headerTest::getFieldValue(*res[0]));
assert_eq("Second value", "B: b", headerTest::getFieldValue(*res[1])); VASSERT_EQ("Second value", "B: b", headerTest::getFieldValue(*res[1]));
assert_eq("Third value", "C: c", headerTest::getFieldValue(*res[2])); VASSERT_EQ("Third value", "C: c", headerTest::getFieldValue(*res[2]));
} }
void testInsertFieldAfter2() void testInsertFieldAfter2()
{ {
vmime::header hdr; vmime::header hdr;
hdr.parse("A: a\r\nC: c\r\n"); hdr.parse("A: a\r\nC: c\r\n");
vmime::ref <vmime::headerField> hf = vmime::headerFieldFactory::getInstance()->create("B", "b"); vmime::ref <vmime::headerField> hf = vmime::headerFieldFactory::getInstance()->create("B", "b");
hdr.insertFieldAfter(0, hf); hdr.insertFieldAfter(0, hf);
std::vector <vmime::ref <vmime::headerField> > res = hdr.getFieldList(); std::vector <vmime::ref <vmime::headerField> > res = hdr.getFieldList();
assert_eq("Count", static_cast <unsigned int>(3), res.size()); VASSERT_EQ("Count", static_cast <unsigned int>(3), res.size());
assert_eq("First value", "A: a", headerTest::getFieldValue(*res[0])); VASSERT_EQ("First value", "A: a", headerTest::getFieldValue(*res[0]));
assert_eq("Second value", "B: b", headerTest::getFieldValue(*res[1])); VASSERT_EQ("Second value", "B: b", headerTest::getFieldValue(*res[1]));
assert_eq("Third value", "C: c", headerTest::getFieldValue(*res[2])); VASSERT_EQ("Third value", "C: c", headerTest::getFieldValue(*res[2]));
} }
// removeField // removeField
void testRemoveField1() void testRemoveField1()
{ {
vmime::header hdr1, hdr2; vmime::header hdr1, hdr2;
hdr1.parse("A: a\r\nB: b\r\nC: c\r\n"); hdr1.parse("A: a\r\nB: b\r\nC: c\r\n");
hdr2.parse("A: a\r\nB: b\r\nC: c\r\n"); hdr2.parse("A: a\r\nB: b\r\nC: c\r\n");
hdr1.removeField(hdr1.getField("B")); hdr1.removeField(hdr1.getField("B"));
hdr2.removeField(1); hdr2.removeField(1);
std::vector <vmime::ref <vmime::headerField> > res1 = hdr1.getFieldList(); std::vector <vmime::ref <vmime::headerField> > res1 = hdr1.getFieldList();
assert_eq("Count", static_cast <unsigned int>(2), res1.size()); VASSERT_EQ("Count", static_cast <unsigned int>(2), res1.size());
assert_eq("First value", "A: a", headerTest::getFieldValue(*res1[0])); VASSERT_EQ("First value", "A: a", headerTest::getFieldValue(*res1[0]));
assert_eq("Second value", "C: c", headerTest::getFieldValue(*res1[1])); VASSERT_EQ("Second value", "C: c", headerTest::getFieldValue(*res1[1]));
std::vector <vmime::ref <vmime::headerField> > res2 = hdr2.getFieldList(); std::vector <vmime::ref <vmime::headerField> > res2 = hdr2.getFieldList();
assert_eq("Count", static_cast <unsigned int>(2), res2.size()); VASSERT_EQ("Count", static_cast <unsigned int>(2), res2.size());
assert_eq("First value", "A: a", headerTest::getFieldValue(*res2[0])); VASSERT_EQ("First value", "A: a", headerTest::getFieldValue(*res2[0]));
assert_eq("Second value", "C: c", headerTest::getFieldValue(*res2[1])); VASSERT_EQ("Second value", "C: c", headerTest::getFieldValue(*res2[1]));
} }
void testRemoveField2() void testRemoveField2()
{ {
vmime::header hdr1, hdr2; vmime::header hdr1, hdr2;
hdr1.parse("A: a\r\n"); hdr1.parse("A: a\r\n");
hdr2.parse("A: a\r\n"); hdr2.parse("A: a\r\n");
hdr1.removeField(hdr1.getField("A")); hdr1.removeField(hdr1.getField("A"));
hdr2.removeField(0); hdr2.removeField(0);
std::vector <vmime::ref <vmime::headerField> > res1 = hdr1.getFieldList(); std::vector <vmime::ref <vmime::headerField> > res1 = hdr1.getFieldList();
assert_eq("Count", static_cast <unsigned int>(0), res1.size()); VASSERT_EQ("Count", static_cast <unsigned int>(0), res1.size());
std::vector <vmime::ref <vmime::headerField> > res2 = hdr2.getFieldList(); std::vector <vmime::ref <vmime::headerField> > res2 = hdr2.getFieldList();
assert_eq("Count", static_cast <unsigned int>(0), res2.size()); VASSERT_EQ("Count", static_cast <unsigned int>(0), res2.size());
} }
// removeAllFields // removeAllFields
void testRemoveAllFields() void testRemoveAllFields()
{ {
vmime::header hdr1, hdr2; vmime::header hdr1, hdr2;
hdr1.parse("A: a\r\n"); hdr1.parse("A: a\r\n");
hdr2.parse("A: a\r\nB: b\r\n"); hdr2.parse("A: a\r\nB: b\r\n");
hdr1.removeAllFields(); hdr1.removeAllFields();
hdr2.removeAllFields(); hdr2.removeAllFields();
std::vector <vmime::ref <vmime::headerField> > res1 = hdr1.getFieldList(); std::vector <vmime::ref <vmime::headerField> > res1 = hdr1.getFieldList();
assert_eq("Count", static_cast <unsigned int>(0), res1.size()); VASSERT_EQ("Count", static_cast <unsigned int>(0), res1.size());
std::vector <vmime::ref <vmime::headerField> > res2 = hdr2.getFieldList(); std::vector <vmime::ref <vmime::headerField> > res2 = hdr2.getFieldList();
assert_eq("Count", static_cast <unsigned int>(0), res2.size()); VASSERT_EQ("Count", static_cast <unsigned int>(0), res2.size());
} }
// getFieldCount // getFieldCount
void testgetFieldCount() void testgetFieldCount()
{ {
vmime::header hdr; vmime::header hdr;
hdr.parse("A: a\r\nB: b\r\nC: c\r\nD: d\r\n"); hdr.parse("A: a\r\nB: b\r\nC: c\r\nD: d\r\n");
assert_eq("Value", 4, hdr.getFieldCount()); VASSERT_EQ("Value", 4, hdr.getFieldCount());
} }
// isEmpty // isEmpty
void testIsEmpty1() void testIsEmpty1()
{ {
vmime::header hdr; vmime::header hdr;
hdr.parse("A: a\r\nB: b\r\nC: c\r\n"); hdr.parse("A: a\r\nB: b\r\nC: c\r\n");
assert_eq("Value", false, hdr.isEmpty()); VASSERT_EQ("Value", false, hdr.isEmpty());
} }
void testIsEmpty2() void testIsEmpty2()
{ {
vmime::header hdr; vmime::header hdr;
hdr.parse("\r\n"); hdr.parse("\r\n");
assert_eq("Value", true, hdr.isEmpty()); VASSERT_EQ("Value", true, hdr.isEmpty());
} }
// getFieldAt // getFieldAt
void getFieldAt() void testGetFieldAt()
{ {
vmime::header hdr; vmime::header hdr;
hdr.parse("B: b\r\nA: a\r\nC: c\r\n"); hdr.parse("B: b\r\nA: a\r\nC: c\r\n");
vmime::ref <vmime::headerField> res = hdr.getFieldAt(2); vmime::ref <vmime::headerField> res = hdr.getFieldAt(2);
assert_eq("Value", "C: c", getFieldValue(*res)); VASSERT_EQ("Value", "C: c", getFieldValue(*res));
} }
// getFieldList // getFieldList
void testGetFieldList1() void testGetFieldList1()
{ {
vmime::header hdr; vmime::header hdr;
hdr.parse("A: a\r\nB: b1\r\nC: c\r\nB: b2\r\n"); hdr.parse("A: a\r\nB: b1\r\nC: c\r\nB: b2\r\n");
std::vector <vmime::ref <vmime::headerField> > res = hdr.getFieldList(); std::vector <vmime::ref <vmime::headerField> > res = hdr.getFieldList();
assert_eq("Count", static_cast <unsigned int>(4), res.size()); VASSERT_EQ("Count", static_cast <unsigned int>(4), res.size());
assert_eq("First value", "A: a", headerTest::getFieldValue(*res[0])); VASSERT_EQ("First value", "A: a", headerTest::getFieldValue(*res[0]));
assert_eq("Second value", "B: b1", headerTest::getFieldValue(*res[1])); VASSERT_EQ("Second value", "B: b1", headerTest::getFieldValue(*res[1]));
assert_eq("Third value", "C: c", headerTest::getFieldValue(*res[2])); VASSERT_EQ("Third value", "C: c", headerTest::getFieldValue(*res[2]));
assert_eq("Thourth value", "B: b2", headerTest::getFieldValue(*res[3])); VASSERT_EQ("Thourth value", "B: b2", headerTest::getFieldValue(*res[3]));
} }
void testGetFieldList2() void testGetFieldList2()
{ {
vmime::header hdr; vmime::header hdr;
hdr.parse("\r\n"); hdr.parse("\r\n");
std::vector <vmime::ref <vmime::headerField> > res = hdr.getFieldList(); std::vector <vmime::ref <vmime::headerField> > res = hdr.getFieldList();
assert_eq("Count", static_cast <unsigned int>(0), res.size()); VASSERT_EQ("Count", static_cast <unsigned int>(0), res.size());
} }
// find function tests // find function tests
void testFind1() void testFind1()
{ {
vmime::header hdr; vmime::header hdr;
hdr.parse("A: a\r\nB: b\r\nC: c\r\nB: d\r\n"); hdr.parse("A: a\r\nB: b\r\nC: c\r\nB: d\r\n");
vmime::ref <vmime::headerField> res = hdr.findField("B"); vmime::ref <vmime::headerField> res = hdr.findField("B");
assert_eq("Value", "B: b", getFieldValue(*res)); VASSERT_EQ("Value", "B: b", getFieldValue(*res));
} }
// getAllByName function tests // getAllByName function tests
void testFindAllFields1() void testFindAllFields1()
{ {
vmime::header hdr; vmime::header hdr;
hdr.parse("A: a1\nC: c1\n"); hdr.parse("A: a1\nC: c1\n");
std::vector <vmime::ref <vmime::headerField> > res = hdr.findAllFields("B"); std::vector <vmime::ref <vmime::headerField> > res = hdr.findAllFields("B");
assert_eq("Count", static_cast <unsigned int>(0), res.size()); VASSERT_EQ("Count", static_cast <unsigned int>(0), res.size());
} }
void testFindAllFields2() void testFindAllFields2()
{ {
vmime::header hdr; vmime::header hdr;
hdr.parse("A: a1\nB: b1\nB: b2\nC: c1\n"); hdr.parse("A: a1\nB: b1\nB: b2\nC: c1\n");
std::vector <vmime::ref <vmime::headerField> > res = hdr.findAllFields("B"); std::vector <vmime::ref <vmime::headerField> > res = hdr.findAllFields("B");
assert_eq("Count", static_cast <unsigned int>(2), res.size()); VASSERT_EQ("Count", static_cast <unsigned int>(2), res.size());
assert_eq("First value", "B: b1", headerTest::getFieldValue(*res[0])); VASSERT_EQ("First value", "B: b1", headerTest::getFieldValue(*res[0]));
assert_eq("Second value", "B: b2", headerTest::getFieldValue(*res[1])); VASSERT_EQ("Second value", "B: b2", headerTest::getFieldValue(*res[1]));
} }
void testFindAllFields3() void testFindAllFields3()
{ {
vmime::header hdr; vmime::header hdr;
hdr.parse("A: a1\nB: b1\nB: b2\nC: c1\nC: c3\nC: c2\n"); hdr.parse("A: a1\nB: b1\nB: b2\nC: c1\nC: c3\nC: c2\n");
std::vector <vmime::ref <vmime::headerField> > res = hdr.findAllFields("C"); std::vector <vmime::ref <vmime::headerField> > res = hdr.findAllFields("C");
assert_eq("Count", static_cast <unsigned int>(3), res.size()); VASSERT_EQ("Count", static_cast <unsigned int>(3), res.size());
assert_eq("First value", "C: c1", headerTest::getFieldValue(*res[0])); VASSERT_EQ("First value", "C: c1", headerTest::getFieldValue(*res[0]));
assert_eq("Second value", "C: c3", headerTest::getFieldValue(*res[1])); VASSERT_EQ("Second value", "C: c3", headerTest::getFieldValue(*res[1]));
assert_eq("Second value", "C: c2", headerTest::getFieldValue(*res[2])); VASSERT_EQ("Second value", "C: c2", headerTest::getFieldValue(*res[2]));
} }
public: VMIME_TEST_SUITE_END
headerTest() : suite("vmime::header")
{
// VMime initialization
vmime::platformDependant::setHandler<vmime::platforms::posix::posixHandler>();
add("Has", testcase(this, "Has1", &headerTest::testHas1));
add("Has", testcase(this, "Has2", &headerTest::testHas2));
add("Append", testcase(this, "Append1", &headerTest::testAppend1));
add("Append", testcase(this, "Append2", &headerTest::testAppend2));
add("InsertFieldBefore", testcase(this, "InsertFieldBefore1", &headerTest::testInsertFieldBefore1));
add("InsertFieldBefore", testcase(this, "InsertFieldBefore2", &headerTest::testInsertFieldBefore2));
add("InsertFieldAfter", testcase(this, "InsertFieldAfter1", &headerTest::testInsertFieldAfter1));
add("InsertFieldAfter", testcase(this, "InsertFieldAfter2", &headerTest::testInsertFieldAfter2));
add("RemoveField", testcase(this, "RemoveField1", &headerTest::testRemoveField1));
add("RemoveField", testcase(this, "RemoveField2", &headerTest::testRemoveField2));
add("RemoveAllFields", testcase(this, "RemoveAllFields", &headerTest::testRemoveAllFields));
add("GetFieldCount", testcase(this, "GetFieldCount", &headerTest::testgetFieldCount));
add("IsEmpty", testcase(this, "IsEmpty1", &headerTest::testIsEmpty1));
add("IsEmpty", testcase(this, "IsEmpty2", &headerTest::testIsEmpty2));
add("GetFieldAt", testcase(this, "GetFieldAt", &headerTest::getFieldAt));
add("GetFieldList", testcase(this, "GetFieldList1", &headerTest::testGetFieldList1));
add("GetFieldList", testcase(this, "GetFieldList2", &headerTest::testGetFieldList2));
add("Find", testcase(this, "Find1", &headerTest::testFind1));
add("FindAllFields", testcase(this, "FindAllFields1", &headerTest::testFindAllFields1));
add("FindAllFields", testcase(this, "FindAllFields2", &headerTest::testFindAllFields2));
add("FindAllFields", testcase(this, "FindAllFields3", &headerTest::testFindAllFields3));
suite::main().add("vmime::header", this);
}
};
headerTest* theTest = new headerTest();
}

View File

@ -17,113 +17,97 @@
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
// //
#include "../lib/unit++/unit++.h" #include "tests/testUtils.hpp"
#include <iostream>
#include <ostream>
#include "vmime/vmime.hpp"
#include "vmime/platforms/posix/posixHandler.hpp"
#include "tests/parser/testUtils.hpp"
using namespace unitpp;
namespace #define VMIME_TEST_SUITE mailboxTest
{ #define VMIME_TEST_SUITE_MODULE "Parser"
class mailboxTest : public suite
VMIME_TEST_SUITE_BEGIN
VMIME_TEST_LIST_BEGIN
VMIME_TEST(testParse)
VMIME_TEST_LIST_END
void testParse()
{ {
void testParse() static const vmime::string testSuitesParse[] =
{ {
static const vmime::string testSuitesParse[] = // Test 1
{ "My (this is a comment)name <me(another \\)comment) @ somewhere(else).com>",
// Test 1
"My (this is a comment)name <me(another \\)comment) @ somewhere(else).com>",
"[address-list: [[mailbox: name=[text: [[word: charset=us-ascii, buffer=My name]]], email=me@somewhere.com]]]", "[address-list: [[mailbox: name=[text: [[word: charset=us-ascii, buffer=My name]]], email=me@somewhere.com]]]",
// Test 2 // Test 2
"mailbox1 <mailbox@one>,;,,, ,, ,,;group1:mailbox1@group1, mailbox2@group2,,\"mailbox #3\" <mailbox3@group2>;, <mailbox@two>,,,,,,,,=?iso-8859-1?q?mailbox_number_3?= <mailbox@three>, =?abc?Q?mailbox?= =?def?Q?_number_4?= <mailbox@four>", "mailbox1 <mailbox@one>,;,,, ,, ,,;group1:mailbox1@group1, mailbox2@group2,,\"mailbox #3\" <mailbox3@group2>;, <mailbox@two>,,,,,,,,=?iso-8859-1?q?mailbox_number_3?= <mailbox@three>, =?abc?Q?mailbox?= =?def?Q?_number_4?= <mailbox@four>",
"[address-list: [[mailbox: name=[text: [[word: charset=us-ascii, buffer=mailbox1]]], email=mailbox@one],[mailbox-group: name=[text: [[word: charset=us-ascii, buffer=group1]]], list=[[mailbox: name=[text: []], email=mailbox1@group1],[mailbox: name=[text: []], email=mailbox2@group2],[mailbox: name=[text: [[word: charset=us-ascii, buffer=mailbox #3]]], email=mailbox3@group2]]],[mailbox: name=[text: []], email=mailbox@two],[mailbox: name=[text: [[word: charset=iso-8859-1, buffer=mailbox number 3]]], email=mailbox@three],[mailbox: name=[text: [[word: charset=abc, buffer=mailbox],[word: charset=def, buffer= number 4]]], email=mailbox@four]]]", "[address-list: [[mailbox: name=[text: [[word: charset=us-ascii, buffer=mailbox1]]], email=mailbox@one],[mailbox-group: name=[text: [[word: charset=us-ascii, buffer=group1]]], list=[[mailbox: name=[text: []], email=mailbox1@group1],[mailbox: name=[text: []], email=mailbox2@group2],[mailbox: name=[text: [[word: charset=us-ascii, buffer=mailbox #3]]], email=mailbox3@group2]]],[mailbox: name=[text: []], email=mailbox@two],[mailbox: name=[text: [[word: charset=iso-8859-1, buffer=mailbox number 3]]], email=mailbox@three],[mailbox: name=[text: [[word: charset=abc, buffer=mailbox],[word: charset=def, buffer= number 4]]], email=mailbox@four]]]",
// Test 3 // Test 3
"John Doe <john.doe@acme.com>", "John Doe <john.doe@acme.com>",
"[address-list: [[mailbox: name=[text: [[word: charset=us-ascii, buffer=John Doe]]], email=john.doe@acme.com]]]", "[address-list: [[mailbox: name=[text: [[word: charset=us-ascii, buffer=John Doe]]], email=john.doe@acme.com]]]",
// Test 4 // Test 4
"john.doe@acme.com (John Doe)", "john.doe@acme.com (John Doe)",
"[address-list: [[mailbox: name=[text: []], email=john.doe@acme.com]]]", "[address-list: [[mailbox: name=[text: []], email=john.doe@acme.com]]]",
// Test 5 // Test 5
"John.Doe (ignore) @acme.com (John Doe)", "John.Doe (ignore) @acme.com (John Doe)",
"[address-list: [[mailbox: name=[text: []], email=John.Doe@acme.com]]]", "[address-list: [[mailbox: name=[text: []], email=John.Doe@acme.com]]]",
// Test 6 // Test 6
"<john.doe@acme.com>", "<john.doe@acme.com>",
"[address-list: [[mailbox: name=[text: []], email=john.doe@acme.com]]]", "[address-list: [[mailbox: name=[text: []], email=john.doe@acme.com]]]",
// Test 7 // Test 7
"john.doe@acme.com", "john.doe@acme.com",
"[address-list: [[mailbox: name=[text: []], email=john.doe@acme.com]]]", "[address-list: [[mailbox: name=[text: []], email=john.doe@acme.com]]]",
// Test 8 // Test 8
"\"John Doe\" <john.doe@acme.com>", "\"John Doe\" <john.doe@acme.com>",
"[address-list: [[mailbox: name=[text: [[word: charset=us-ascii, buffer=John Doe]]], email=john.doe@acme.com]]]", "[address-list: [[mailbox: name=[text: [[word: charset=us-ascii, buffer=John Doe]]], email=john.doe@acme.com]]]",
// Test 9 // Test 9
"=?us-ascii?q?John?=<john.doe@acme.com>", "=?us-ascii?q?John?=<john.doe@acme.com>",
"[address-list: [[mailbox: name=[text: [[word: charset=us-ascii, buffer=John]]], email=john.doe@acme.com]]]", "[address-list: [[mailbox: name=[text: [[word: charset=us-ascii, buffer=John]]], email=john.doe@acme.com]]]",
// Test 10 // Test 10
"\"John\"<john.doe@acme.com>", "\"John\"<john.doe@acme.com>",
"[address-list: [[mailbox: name=[text: [[word: charset=us-ascii, buffer=John]]], email=john.doe@acme.com]]]", "[address-list: [[mailbox: name=[text: [[word: charset=us-ascii, buffer=John]]], email=john.doe@acme.com]]]",
// Test 11 // Test 11
"John<john.doe@acme.com>", "John<john.doe@acme.com>",
"[address-list: [[mailbox: name=[text: [[word: charset=us-ascii, buffer=John]]], email=john.doe@acme.com]]]" "[address-list: [[mailbox: name=[text: [[word: charset=us-ascii, buffer=John]]], email=john.doe@acme.com]]]"
}; };
for (unsigned int i = 0 ; i < sizeof(testSuitesParse) / sizeof(testSuitesParse[0]) / 2 ; ++i) for (unsigned int i = 0 ; i < sizeof(testSuitesParse) / sizeof(testSuitesParse[0]) / 2 ; ++i)
{
vmime::string in = testSuitesParse[i * 2];
vmime::string out = testSuitesParse[i * 2 + 1];
std::ostringstream oss;
oss << "Test " << (i + 1);
vmime::addressList addrList;
addrList.parse(in);
std::ostringstream cmp;
cmp << addrList;
assert_eq(oss.str(), out, cmp.str());
}
}
public:
mailboxTest() : suite("vmime::mailbox")
{ {
vmime::platformDependant::setHandler<vmime::platforms::posix::posixHandler>(); vmime::string in = testSuitesParse[i * 2];
vmime::string out = testSuitesParse[i * 2 + 1];
add("Parse", testcase(this, "Parse", &mailboxTest::testParse)); std::ostringstream oss;
oss << "Test " << (i + 1);
suite::main().add("vmime::mailbox", this); vmime::addressList addrList;
addrList.parse(in);
std::ostringstream cmp;
cmp << addrList;
VASSERT_EQ(oss.str(), out, cmp.str());
} }
}
}; VMIME_TEST_SUITE_END
mailboxTest* theTest = new mailboxTest();
}

View File

@ -17,99 +17,85 @@
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
// //
#include "../lib/unit++/unit++.h" #include "tests/testUtils.hpp"
#include <iostream>
#include <ostream>
#include "vmime/vmime.hpp"
#include "vmime/platforms/posix/posixHandler.hpp"
using namespace unitpp;
namespace #define VMIME_TEST_SUITE mediaTypeTest
{ #define VMIME_TEST_SUITE_MODULE "Parser"
class mediaTypeTest : public suite
VMIME_TEST_SUITE_BEGIN
VMIME_TEST_LIST_BEGIN
VMIME_TEST(testConstructors)
VMIME_TEST(testCopy)
VMIME_TEST(testSetFromString)
VMIME_TEST(testParse)
VMIME_TEST(testGenerate)
VMIME_TEST_LIST_END
void testConstructors()
{ {
void testConstructors() vmime::mediaType t1;
{
vmime::mediaType t1;
assert_eq("1.1", vmime::mediaTypes::APPLICATION, t1.getType()); VASSERT_EQ("1.1", vmime::mediaTypes::APPLICATION, t1.getType());
assert_eq("1.2", vmime::mediaTypes::APPLICATION_OCTET_STREAM, t1.getSubType()); VASSERT_EQ("1.2", vmime::mediaTypes::APPLICATION_OCTET_STREAM, t1.getSubType());
vmime::mediaType t2("type", "sub"); vmime::mediaType t2("type", "sub");
assert_eq("2.1", "type", t2.getType()); VASSERT_EQ("2.1", "type", t2.getType());
assert_eq("2.2", "sub", t2.getSubType()); VASSERT_EQ("2.2", "sub", t2.getSubType());
vmime::mediaType t3("type/sub"); vmime::mediaType t3("type/sub");
assert_eq("3.1", "type", t3.getType()); VASSERT_EQ("3.1", "type", t3.getType());
assert_eq("3.2", "sub", t3.getSubType()); VASSERT_EQ("3.2", "sub", t3.getSubType());
} }
void testCopy() void testCopy()
{ {
vmime::mediaType t1("type/sub"); vmime::mediaType t1("type/sub");
assert_eq("eq1", "type", t1.getType()); VASSERT_EQ("eq1", "type", t1.getType());
assert_eq("eq2", "sub", t1.getSubType()); VASSERT_EQ("eq2", "sub", t1.getSubType());
assert_true("operator==", t1 == t1); VASSERT("operator==", t1 == t1);
assert_true("clone", t1 == *vmime::clone(t1)); VASSERT("clone", t1 == *vmime::clone(t1));
assert_eq("eq3", "type", vmime::clone(t1)->getType()); VASSERT_EQ("eq3", "type", vmime::clone(t1)->getType());
assert_eq("eq4", "sub", vmime::clone(t1)->getSubType()); VASSERT_EQ("eq4", "sub", vmime::clone(t1)->getSubType());
vmime::mediaType t2; vmime::mediaType t2;
t2.copyFrom(t1); t2.copyFrom(t1);
assert_true("copyFrom", t1 == t2); VASSERT("copyFrom", t1 == t2);
} }
void testSetFromString() void testSetFromString()
{ {
vmime::mediaType t1; vmime::mediaType t1;
t1.setFromString("type/sub"); t1.setFromString("type/sub");
assert_eq("1.1", "type", t1.getType()); VASSERT_EQ("1.1", "type", t1.getType());
assert_eq("1.2", "sub", t1.getSubType()); VASSERT_EQ("1.2", "sub", t1.getSubType());
} }
void testParse() void testParse()
{ {
vmime::mediaType t1; vmime::mediaType t1;
t1.parse("type/sub"); t1.parse("type/sub");
assert_eq("1.1", "type", t1.getType()); VASSERT_EQ("1.1", "type", t1.getType());
assert_eq("1.2", "sub", t1.getSubType()); VASSERT_EQ("1.2", "sub", t1.getSubType());
} }
void testGenerate() void testGenerate()
{ {
vmime::mediaType t1("type", "sub"); vmime::mediaType t1("type", "sub");
assert_eq("1", "type/sub", t1.generate()); VASSERT_EQ("1", "type/sub", t1.generate());
} }
public: VMIME_TEST_SUITE_END
mediaTypeTest() : suite("vmime::mediaType")
{
vmime::platformDependant::setHandler<vmime::platforms::posix::posixHandler>();
add("Constructors", testcase(this, "Constructors", &mediaTypeTest::testConstructors));
add("Copy", testcase(this, "Copy", &mediaTypeTest::testCopy));
add("SetFromString", testcase(this, "SetFromString", &mediaTypeTest::testSetFromString));
add("Parse", testcase(this, "Parse", &mediaTypeTest::testParse));
add("Generate", testcase(this, "Generate", &mediaTypeTest::testGenerate));
suite::main().add("vmime::mediaType", this);
}
};
mediaTypeTest* theTest = new mediaTypeTest();
}

View File

@ -17,79 +17,63 @@
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
// //
#include "../lib/unit++/unit++.h" #include "tests/testUtils.hpp"
#include <iostream>
#include <ostream>
#include "vmime/vmime.hpp"
#include "vmime/platforms/posix/posixHandler.hpp"
#include "tests/parser/testUtils.hpp"
using namespace unitpp;
namespace #define VMIME_TEST_SUITE messageIdSequenceTest
{ #define VMIME_TEST_SUITE_MODULE "Parser"
class messageIdSequenceTest : public suite
VMIME_TEST_SUITE_BEGIN
VMIME_TEST_LIST_BEGIN
VMIME_TEST(testParse)
VMIME_TEST(testGenerate)
VMIME_TEST_LIST_END
void testParse()
{ {
void testParse() vmime::messageIdSequence s1;
{ s1.parse("");
vmime::messageIdSequence s1;
s1.parse("");
assert_eq("1", 0, s1.getMessageIdCount()); VASSERT_EQ("1", 0, s1.getMessageIdCount());
vmime::messageIdSequence s2; vmime::messageIdSequence s2;
s2.parse(" \t "); s2.parse(" \t ");
assert_eq("2", 0, s2.getMessageIdCount()); VASSERT_EQ("2", 0, s2.getMessageIdCount());
vmime::messageIdSequence s3; vmime::messageIdSequence s3;
s3.parse("<a@b>"); s3.parse("<a@b>");
assert_eq("3.1", 1, s3.getMessageIdCount()); VASSERT_EQ("3.1", 1, s3.getMessageIdCount());
assert_eq("3.2", "a", s3.getMessageIdAt(0)->getLeft()); VASSERT_EQ("3.2", "a", s3.getMessageIdAt(0)->getLeft());
assert_eq("3.3", "b", s3.getMessageIdAt(0)->getRight()); VASSERT_EQ("3.3", "b", s3.getMessageIdAt(0)->getRight());
vmime::messageIdSequence s4; vmime::messageIdSequence s4;
s4.parse("<a@b> \r\n\t<c@d>"); s4.parse("<a@b> \r\n\t<c@d>");
assert_eq("4.1", 2, s4.getMessageIdCount()); VASSERT_EQ("4.1", 2, s4.getMessageIdCount());
assert_eq("4.2", "a", s4.getMessageIdAt(0)->getLeft()); VASSERT_EQ("4.2", "a", s4.getMessageIdAt(0)->getLeft());
assert_eq("4.3", "b", s4.getMessageIdAt(0)->getRight()); VASSERT_EQ("4.3", "b", s4.getMessageIdAt(0)->getRight());
assert_eq("4.4", "c", s4.getMessageIdAt(1)->getLeft()); VASSERT_EQ("4.4", "c", s4.getMessageIdAt(1)->getLeft());
assert_eq("4.5", "d", s4.getMessageIdAt(1)->getRight()); VASSERT_EQ("4.5", "d", s4.getMessageIdAt(1)->getRight());
} }
void testGenerate() void testGenerate()
{ {
vmime::messageIdSequence s1; vmime::messageIdSequence s1;
s1.appendMessageId(vmime::create <vmime::messageId>("a", "b")); s1.appendMessageId(vmime::create <vmime::messageId>("a", "b"));
assert_eq("1", "<a@b>", s1.generate()); VASSERT_EQ("1", "<a@b>", s1.generate());
vmime::messageIdSequence s2; vmime::messageIdSequence s2;
s2.appendMessageId(vmime::create <vmime::messageId>("a", "b")); s2.appendMessageId(vmime::create <vmime::messageId>("a", "b"));
s2.appendMessageId(vmime::create <vmime::messageId>("c", "d")); s2.appendMessageId(vmime::create <vmime::messageId>("c", "d"));
assert_eq("2", "<a@b> <c@d>", s2.generate()); VASSERT_EQ("2", "<a@b> <c@d>", s2.generate());
} }
public: VMIME_TEST_SUITE_END
messageIdSequenceTest() : suite("vmime::messageIdSequence")
{
vmime::platformDependant::setHandler<vmime::platforms::posix::posixHandler>();
add("Parse", testcase(this, "Parse", &messageIdSequenceTest::testParse));
add("Generate", testcase(this, "Generate", &messageIdSequenceTest::testGenerate));
suite::main().add("vmime::messageIdSequence", this);
}
};
messageIdSequenceTest* theTest = new messageIdSequenceTest();
}

View File

@ -17,68 +17,52 @@
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
// //
#include "../lib/unit++/unit++.h" #include "tests/testUtils.hpp"
#include <iostream>
#include <ostream>
#include "vmime/vmime.hpp"
#include "vmime/platforms/posix/posixHandler.hpp"
#include "tests/parser/testUtils.hpp"
using namespace unitpp;
namespace #define VMIME_TEST_SUITE messageIdTest
{ #define VMIME_TEST_SUITE_MODULE "Parser"
class messageIdTest : public suite
VMIME_TEST_SUITE_BEGIN
VMIME_TEST_LIST_BEGIN
VMIME_TEST(testParse)
VMIME_TEST(testGenerate)
VMIME_TEST_LIST_END
void testParse()
{ {
void testParse() vmime::messageId m1;
{ m1.parse("<a@b>");
vmime::messageId m1;
m1.parse("<a@b>");
assert_eq("1.1", "a", m1.getLeft()); VASSERT_EQ("1.1", "a", m1.getLeft());
assert_eq("1.2", "b", m1.getRight()); VASSERT_EQ("1.2", "b", m1.getRight());
} }
void testGenerate() void testGenerate()
{ {
vmime::messageId m1; vmime::messageId m1;
assert_eq("1", "<@>", m1.generate()); VASSERT_EQ("1", "<@>", m1.generate());
vmime::messageId m2; vmime::messageId m2;
m2.setLeft("a"); m2.setLeft("a");
assert_eq("2", "<a@>", m2.generate()); VASSERT_EQ("2", "<a@>", m2.generate());
vmime::messageId m3; vmime::messageId m3;
m3.setRight("b"); m3.setRight("b");
assert_eq("3", "<@b>", m3.generate()); VASSERT_EQ("3", "<@b>", m3.generate());
vmime::messageId m4; vmime::messageId m4;
m4.setLeft("a"); m4.setLeft("a");
m4.setRight("b"); m4.setRight("b");
assert_eq("4", "<a@b>", m4.generate()); VASSERT_EQ("4", "<a@b>", m4.generate());
} }
public: VMIME_TEST_SUITE_END
messageIdTest() : suite("vmime::messageId")
{
vmime::platformDependant::setHandler<vmime::platforms::posix::posixHandler>();
add("Parse", testcase(this, "Parse", &messageIdTest::testParse));
add("Generate", testcase(this, "Generate", &messageIdTest::testGenerate));
suite::main().add("vmime::messageId", this);
}
};
messageIdTest* theTest = new messageIdTest();
}

View File

@ -17,21 +17,21 @@
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
// //
#include "../lib/unit++/unit++.h" #include "tests/testUtils.hpp"
#include <iostream>
#include <ostream> #define VMIME_TEST_SUITE parameterTest
#define VMIME_TEST_SUITE_MODULE "Parser"
#include "vmime/vmime.hpp"
#include "vmime/platforms/posix/posixHandler.hpp"
VMIME_TEST_SUITE_BEGIN
#include "tests/parser/testUtils.hpp"
VMIME_TEST_LIST_BEGIN
using namespace unitpp; VMIME_TEST(testParse)
VMIME_TEST(testGenerate)
VMIME_TEST_LIST_END
namespace
{
// HACK: parameterizedHeaderField constructor is private // HACK: parameterizedHeaderField constructor is private
class parameterizedHeaderField : public vmime::parameterizedHeaderField class parameterizedHeaderField : public vmime::parameterizedHeaderField
{ {
@ -65,193 +65,177 @@ namespace
(p.getParameterAt(n).staticCast <vmime::defaultParameter>())->getValue().getBuffer()) (p.getParameterAt(n).staticCast <vmime::defaultParameter>())->getValue().getBuffer())
class parameterTest : public suite void testParse()
{ {
void testParse() // Simple parameter
{ parameterizedHeaderField p1;
// Simple parameter p1.parse("X; param1=value1;\r\n");
parameterizedHeaderField p1;
p1.parse("X; param1=value1;\r\n");
assert_eq("1.1", 1, p1.getParameterCount()); VASSERT_EQ("1.1", 1, p1.getParameterCount());
assert_eq("1.2", "param1", PARAM_NAME(p1, 0)); VASSERT_EQ("1.2", "param1", PARAM_NAME(p1, 0));
assert_eq("1.3", "value1", PARAM_VALUE(p1, 0)); VASSERT_EQ("1.3", "value1", PARAM_VALUE(p1, 0));
// Multi-section parameters (1/2) // Multi-section parameters (1/2)
parameterizedHeaderField p2a; parameterizedHeaderField p2a;
p2a.parse("X; param1=value1;\r\n" p2a.parse("X; param1=value1;\r\n"
" param2*0=\"val\";\r\n" " param2*0=\"val\";\r\n"
" param2*1=\"ue2\";"); " param2*1=\"ue2\";");
assert_eq("2a.1", 2, p2a.getParameterCount()); VASSERT_EQ("2a.1", 2, p2a.getParameterCount());
assert_eq("2a.2", "param1", PARAM_NAME(p2a, 0)); VASSERT_EQ("2a.2", "param1", PARAM_NAME(p2a, 0));
assert_eq("2a.3", "value1", PARAM_VALUE(p2a, 0)); VASSERT_EQ("2a.3", "value1", PARAM_VALUE(p2a, 0));
assert_eq("2a.4", "param2", PARAM_NAME(p2a, 1)); VASSERT_EQ("2a.4", "param2", PARAM_NAME(p2a, 1));
assert_eq("2a.5", "value2", PARAM_VALUE(p2a, 1)); VASSERT_EQ("2a.5", "value2", PARAM_VALUE(p2a, 1));
// Multi-section parameters (2/2) // Multi-section parameters (2/2)
parameterizedHeaderField p2b; parameterizedHeaderField p2b;
p2b.parse("X; param1=value1;\r\n" p2b.parse("X; param1=value1;\r\n"
" param2=\"should be ignored\";\r\n" " param2=\"should be ignored\";\r\n"
" param2*0=\"val\";\r\n" " param2*0=\"val\";\r\n"
" param2*1=\"ue2\";"); " param2*1=\"ue2\";");
assert_eq("2b.1", 2, p2b.getParameterCount()); VASSERT_EQ("2b.1", 2, p2b.getParameterCount());
assert_eq("2b.2", "param1", PARAM_NAME(p2b, 0)); VASSERT_EQ("2b.2", "param1", PARAM_NAME(p2b, 0));
assert_eq("2b.3", "value1", PARAM_VALUE(p2b, 0)); VASSERT_EQ("2b.3", "value1", PARAM_VALUE(p2b, 0));
assert_eq("2b.4", "param2", PARAM_NAME(p2b, 1)); VASSERT_EQ("2b.4", "param2", PARAM_NAME(p2b, 1));
assert_eq("2b.5", "value2", PARAM_VALUE(p2b, 1)); VASSERT_EQ("2b.5", "value2", PARAM_VALUE(p2b, 1));
// Extended parameter (charset and language information) // Extended parameter (charset and language information)
parameterizedHeaderField p3; parameterizedHeaderField p3;
p3.parse("X; param1*=charset'language'value1;\r\n"); p3.parse("X; param1*=charset'language'value1;\r\n");
assert_eq("3.1", 1, p3.getParameterCount()); VASSERT_EQ("3.1", 1, p3.getParameterCount());
assert_eq("3.2", "param1", PARAM_NAME(p3, 0)); VASSERT_EQ("3.2", "param1", PARAM_NAME(p3, 0));
assert_eq("3.3", "charset", PARAM_CHARSET(p3, 0)); VASSERT_EQ("3.3", "charset", PARAM_CHARSET(p3, 0));
assert_eq("3.4", "value1", PARAM_BUFFER(p3, 0)); VASSERT_EQ("3.4", "value1", PARAM_BUFFER(p3, 0));
// Encoded characters in extended parameter values // Encoded characters in extended parameter values
parameterizedHeaderField p4; parameterizedHeaderField p4;
p4.parse("X; param1*=a%20value%20with%20multiple%20word%73"); // 0x73 = 's' p4.parse("X; param1*=a%20value%20with%20multiple%20word%73"); // 0x73 = 's'
assert_eq("4.1", 1, p4.getParameterCount()); VASSERT_EQ("4.1", 1, p4.getParameterCount());
assert_eq("4.2", "param1", PARAM_NAME(p4, 0)); VASSERT_EQ("4.2", "param1", PARAM_NAME(p4, 0));
assert_eq("4.3", "a value with multiple words", PARAM_VALUE(p4, 0)); VASSERT_EQ("4.3", "a value with multiple words", PARAM_VALUE(p4, 0));
// Invalid encoded character // Invalid encoded character
parameterizedHeaderField p5; parameterizedHeaderField p5;
p5.parse("X; param1*=test%20value%"); p5.parse("X; param1*=test%20value%");
assert_eq("5.1", 1, p5.getParameterCount()); VASSERT_EQ("5.1", 1, p5.getParameterCount());
assert_eq("5.2", "param1", PARAM_NAME(p5, 0)); VASSERT_EQ("5.2", "param1", PARAM_NAME(p5, 0));
assert_eq("5.3", "test value%", PARAM_VALUE(p5, 0)); VASSERT_EQ("5.3", "test value%", PARAM_VALUE(p5, 0));
// Spaces before and after '=' // Spaces before and after '='
parameterizedHeaderField p6; parameterizedHeaderField p6;
p6.parse("X; param1\t= \"value1\""); p6.parse("X; param1\t= \"value1\"");
assert_eq("6.1", 1, p6.getParameterCount()); VASSERT_EQ("6.1", 1, p6.getParameterCount());
assert_eq("6.2", "param1", PARAM_NAME(p6, 0)); VASSERT_EQ("6.2", "param1", PARAM_NAME(p6, 0));
assert_eq("6.3", "value1", PARAM_VALUE(p6, 0)); VASSERT_EQ("6.3", "value1", PARAM_VALUE(p6, 0));
// Quoted strings and escaped chars // Quoted strings and escaped chars
parameterizedHeaderField p7; parameterizedHeaderField p7;
p7.parse("X; param1=\"this is a slash: \\\"\\\\\\\"\""); // \"\\\" p7.parse("X; param1=\"this is a slash: \\\"\\\\\\\"\""); // \"\\\"
assert_eq("7.1", 1, p7.getParameterCount()); VASSERT_EQ("7.1", 1, p7.getParameterCount());
assert_eq("7.2", "param1", PARAM_NAME(p7, 0)); VASSERT_EQ("7.2", "param1", PARAM_NAME(p7, 0));
assert_eq("7.3", "this is a slash: \"\\\"", PARAM_VALUE(p7, 0)); VASSERT_EQ("7.3", "this is a slash: \"\\\"", PARAM_VALUE(p7, 0));
// Extended parameter with charset specified in more than one // Extended parameter with charset specified in more than one
// section (this is forbidden by RFC, but is should not fail) // section (this is forbidden by RFC, but is should not fail)
parameterizedHeaderField p8; parameterizedHeaderField p8;
p8.parse("X; param1*0*=charset1'language1'value1;\r\n" p8.parse("X; param1*0*=charset1'language1'value1;\r\n"
" param1*1*=charset2'language2'value2;"); " param1*1*=charset2'language2'value2;");
assert_eq("8.1", 1, p8.getParameterCount()); VASSERT_EQ("8.1", 1, p8.getParameterCount());
assert_eq("8.2", "param1", PARAM_NAME(p8, 0)); VASSERT_EQ("8.2", "param1", PARAM_NAME(p8, 0));
assert_eq("8.3", "charset1", PARAM_CHARSET(p8, 0)); VASSERT_EQ("8.3", "charset1", PARAM_CHARSET(p8, 0));
assert_eq("8.4", "value1charset2'language2'value2", PARAM_BUFFER(p8, 0)); VASSERT_EQ("8.4", "value1charset2'language2'value2", PARAM_BUFFER(p8, 0));
// Charset not specified in the first section (that is not encoded), // Charset not specified in the first section (that is not encoded),
// but specified in the second one (legal) // but specified in the second one (legal)
parameterizedHeaderField p9; parameterizedHeaderField p9;
p9.parse("X; param1*0=value1;\r\n" p9.parse("X; param1*0=value1;\r\n"
" param1*1*=charset'language'value2;"); " param1*1*=charset'language'value2;");
assert_eq("9.1", 1, p9.getParameterCount()); VASSERT_EQ("9.1", 1, p9.getParameterCount());
assert_eq("9.2", "param1", PARAM_NAME(p9, 0)); VASSERT_EQ("9.2", "param1", PARAM_NAME(p9, 0));
assert_eq("9.3", "charset", PARAM_CHARSET(p9, 0)); VASSERT_EQ("9.3", "charset", PARAM_CHARSET(p9, 0));
assert_eq("9.4", "value1value2", PARAM_BUFFER(p9, 0)); VASSERT_EQ("9.4", "value1value2", PARAM_BUFFER(p9, 0));
// Characters prefixed with '%' in a simple (not extended) section // Characters prefixed with '%' in a simple (not extended) section
// should not be decoded // should not be decoded
parameterizedHeaderField p10; parameterizedHeaderField p10;
p10.parse("X; param1=val%20ue1"); p10.parse("X; param1=val%20ue1");
assert_eq("10.1", 1, p10.getParameterCount()); VASSERT_EQ("10.1", 1, p10.getParameterCount());
assert_eq("10.2", "param1", PARAM_NAME(p10, 0)); VASSERT_EQ("10.2", "param1", PARAM_NAME(p10, 0));
assert_eq("10.3", "val%20ue1", PARAM_VALUE(p10, 0)); VASSERT_EQ("10.3", "val%20ue1", PARAM_VALUE(p10, 0));
// Multiple sections + charset specified and encoding // Multiple sections + charset specified and encoding
parameterizedHeaderField p11; parameterizedHeaderField p11;
p11.parse("X; param1*0*=charset'language'value1a%20;" p11.parse("X; param1*0*=charset'language'value1a%20;"
" param1*1*=value1b%20;" " param1*1*=value1b%20;"
" param1*2=value1c"); " param1*2=value1c");
assert_eq("11.1", 1, p11.getParameterCount()); VASSERT_EQ("11.1", 1, p11.getParameterCount());
assert_eq("11.2", "param1", PARAM_NAME(p11, 0)); VASSERT_EQ("11.2", "param1", PARAM_NAME(p11, 0));
assert_eq("11.3", "charset", PARAM_CHARSET(p11, 0)); VASSERT_EQ("11.3", "charset", PARAM_CHARSET(p11, 0));
assert_eq("11.4", "value1a value1b value1c", PARAM_BUFFER(p11, 0)); VASSERT_EQ("11.4", "value1a value1b value1c", PARAM_BUFFER(p11, 0));
// No charset specified: defaults to US-ASCII // No charset specified: defaults to US-ASCII
parameterizedHeaderField p12; parameterizedHeaderField p12;
p12.parse("X; param1*='language'value1"); p12.parse("X; param1*='language'value1");
assert_eq("12.1", 1, p12.getParameterCount()); VASSERT_EQ("12.1", 1, p12.getParameterCount());
assert_eq("12.2", "param1", PARAM_NAME(p12, 0)); VASSERT_EQ("12.2", "param1", PARAM_NAME(p12, 0));
assert_eq("12.3", "us-ascii", PARAM_CHARSET(p12, 0)); VASSERT_EQ("12.3", "us-ascii", PARAM_CHARSET(p12, 0));
assert_eq("12.4", "value1", PARAM_BUFFER(p12, 0)); VASSERT_EQ("12.4", "value1", PARAM_BUFFER(p12, 0));
} }
void testGenerate() void testGenerate()
{ {
// Simple parameter/value // Simple parameter/value
parameterizedHeaderField p1; parameterizedHeaderField p1;
p1.appendParameter(vmime::parameterFactory::getInstance()->create("param1", "value1")); p1.appendParameter(vmime::parameterFactory::getInstance()->create("param1", "value1"));
assert_eq("1", "F: X; param1=value1", p1.generate()); VASSERT_EQ("1", "F: X; param1=value1", p1.generate());
// Value that needs quoting (1/2) // Value that needs quoting (1/2)
parameterizedHeaderField p2a; parameterizedHeaderField p2a;
p2a.appendParameter(vmime::parameterFactory::getInstance()->create("param1", "value1a;value1b")); p2a.appendParameter(vmime::parameterFactory::getInstance()->create("param1", "value1a;value1b"));
assert_eq("2a", "F: X; param1=\"value1a;value1b\"", p2a.generate()); VASSERT_EQ("2a", "F: X; param1=\"value1a;value1b\"", p2a.generate());
// Value that needs quoting (2/2) // Value that needs quoting (2/2)
parameterizedHeaderField p2b; parameterizedHeaderField p2b;
p2b.appendParameter(vmime::parameterFactory::getInstance()->create("param1", "va\\lue\"1")); p2b.appendParameter(vmime::parameterFactory::getInstance()->create("param1", "va\\lue\"1"));
assert_eq("2b", "F: X; param1=\"va\\\\lue\\\"1\"", p2b.generate()); VASSERT_EQ("2b", "F: X; param1=\"va\\\\lue\\\"1\"", p2b.generate());
// Extended parameter with charset specifier // Extended parameter with charset specifier
parameterizedHeaderField p3; parameterizedHeaderField p3;
p3.appendParameter(vmime::parameterFactory::getInstance()->create("param1", p3.appendParameter(vmime::parameterFactory::getInstance()->create("param1",
vmime::word("value 1\xe9", vmime::charset("charset")))); vmime::word("value 1\xe9", vmime::charset("charset"))));
assert_eq("3", "F: X; param1=\"value 1\";param1*=charset''value%201%E9", p3.generate()); VASSERT_EQ("3", "F: X; param1=\"value 1\";param1*=charset''value%201%E9", p3.generate());
// Value that spans on multiple lines // Value that spans on multiple lines
parameterizedHeaderField p4; parameterizedHeaderField p4;
p4.appendParameter(vmime::parameterFactory::getInstance()->create("param1", p4.appendParameter(vmime::parameterFactory::getInstance()->create("param1",
vmime::word("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ", vmime::word("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ",
vmime::charset("charset")))); vmime::charset("charset"))));
assert_eq("4", "F: X; \r\n " VASSERT_EQ("4", "F: X; \r\n "
"param1=abcdefghijklm;\r\n " "param1=abcdefghijklm;\r\n "
"param1*0*=charset''abc;\r\n " "param1*0*=charset''abc;\r\n "
"param1*1*=defghijkl;\r\n " "param1*1*=defghijkl;\r\n "
"param1*2*=mnopqrstu;\r\n " "param1*2*=mnopqrstu;\r\n "
"param1*3*=vwxyzABCD;\r\n " "param1*3*=vwxyzABCD;\r\n "
"param1*4*=EFGHIJKLM;\r\n " "param1*4*=EFGHIJKLM;\r\n "
"param1*5*=NOPQRSTUV;\r\n " "param1*5*=NOPQRSTUV;\r\n "
"param1*6*=WXYZ", p4.generate(25)); // max line length = 25 "param1*6*=WXYZ", p4.generate(25)); // max line length = 25
} }
public: VMIME_TEST_SUITE_END
parameterTest() : suite("vmime::path")
{
vmime::platformDependant::setHandler<vmime::platforms::posix::posixHandler>();
add("Parse", testcase(this, "Parse", &parameterTest::testParse));
add("Generate", testcase(this, "Generate", &parameterTest::testGenerate));
suite::main().add("vmime::parameter", this);
}
};
parameterTest* theTest = new parameterTest();
}

View File

@ -17,103 +17,87 @@
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
// //
#include "../lib/unit++/unit++.h" #include "tests/testUtils.hpp"
#include <iostream>
#include <ostream>
#include "vmime/vmime.hpp"
#include "vmime/platforms/posix/posixHandler.hpp"
#include "tests/parser/testUtils.hpp"
using namespace unitpp;
namespace #define VMIME_TEST_SUITE pathTest
{ #define VMIME_TEST_SUITE_MODULE "Parser"
class pathTest : public suite
VMIME_TEST_SUITE_BEGIN
VMIME_TEST_LIST_BEGIN
VMIME_TEST(testParse)
VMIME_TEST(testParse2)
VMIME_TEST(testGenerate)
VMIME_TEST_LIST_END
void testParse()
{ {
void testParse() vmime::path p1;
{ p1.parse("<>");
vmime::path p1;
p1.parse("<>");
assert_eq("1.1", "", p1.getLocalPart()); VASSERT_EQ("1.1", "", p1.getLocalPart());
assert_eq("1.2", "", p1.getDomain()); VASSERT_EQ("1.2", "", p1.getDomain());
vmime::path p2; vmime::path p2;
p2.parse("<domain>"); p2.parse("<domain>");
assert_eq("2.1", "", p2.getLocalPart()); VASSERT_EQ("2.1", "", p2.getLocalPart());
assert_eq("2.2", "domain", p2.getDomain()); VASSERT_EQ("2.2", "domain", p2.getDomain());
vmime::path p3; vmime::path p3;
p3.parse("<local@domain>"); p3.parse("<local@domain>");
assert_eq("3.1", "local", p3.getLocalPart()); VASSERT_EQ("3.1", "local", p3.getLocalPart());
assert_eq("3.2", "domain", p3.getDomain()); VASSERT_EQ("3.2", "domain", p3.getDomain());
} }
void testParse2() void testParse2()
{ {
// Test some invalid paths (no '<>') // Test some invalid paths (no '<>')
vmime::path p1; vmime::path p1;
p1.parse(""); p1.parse("");
assert_eq("1.1", "", p1.getLocalPart()); VASSERT_EQ("1.1", "", p1.getLocalPart());
assert_eq("1.2", "", p1.getDomain()); VASSERT_EQ("1.2", "", p1.getDomain());
vmime::path p2; vmime::path p2;
p2.parse("domain"); p2.parse("domain");
assert_eq("2.1", "", p2.getLocalPart()); VASSERT_EQ("2.1", "", p2.getLocalPart());
assert_eq("2.2", "domain", p2.getDomain()); VASSERT_EQ("2.2", "domain", p2.getDomain());
vmime::path p3; vmime::path p3;
p3.parse("local@domain"); p3.parse("local@domain");
assert_eq("3.1", "local", p3.getLocalPart()); VASSERT_EQ("3.1", "local", p3.getLocalPart());
assert_eq("3.2", "domain", p3.getDomain()); VASSERT_EQ("3.2", "domain", p3.getDomain());
} }
void testGenerate() void testGenerate()
{ {
vmime::path p1; vmime::path p1;
assert_eq("1", "<>", p1.generate()); VASSERT_EQ("1", "<>", p1.generate());
vmime::path p2; vmime::path p2;
p2.setLocalPart("local"); p2.setLocalPart("local");
assert_eq("2", "<local@>", p2.generate()); VASSERT_EQ("2", "<local@>", p2.generate());
vmime::path p3; vmime::path p3;
p3.setDomain("domain"); p3.setDomain("domain");
assert_eq("3", "<@domain>", p3.generate()); VASSERT_EQ("3", "<@domain>", p3.generate());
vmime::path p4; vmime::path p4;
p4.setLocalPart("local"); p4.setLocalPart("local");
p4.setDomain("domain"); p4.setDomain("domain");
assert_eq("4", "<local@domain>", p4.generate()); VASSERT_EQ("4", "<local@domain>", p4.generate());
} }
public: VMIME_TEST_SUITE_END
pathTest() : suite("vmime::path")
{
vmime::platformDependant::setHandler<vmime::platforms::posix::posixHandler>();
add("Parse", testcase(this, "Parse", &pathTest::testParse));
add("Parse2", testcase(this, "Parse2", &pathTest::testParse2));
add("Generate", testcase(this, "Generate", &pathTest::testGenerate));
suite::main().add("vmime::path", this);
}
};
pathTest* theTest = new pathTest();
}

View File

@ -1,123 +0,0 @@
//
// VMime library (http://www.vmime.org)
// Copyright (C) 2002-2005 Vincent Richard <vincent@vincent-richard.net>
//
// 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 2 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, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//
#include <ostream>
namespace std
{
std::ostream& operator<<(std::ostream& os, const vmime::charset& ch)
{
os << "[charset: " << ch.getName() << "]";
return (os);
}
std::ostream& operator<<(std::ostream& os, const vmime::text& txt)
{
os << "[text: [";
for (int i = 0 ; i < txt.getWordCount() ; ++i)
{
const vmime::word& w = *txt.getWordAt(i);
if (i != 0)
os << ",";
os << "[word: charset=" << w.getCharset().getName() << ", buffer=" << w.getBuffer() << "]";
}
os << "]]";
return (os);
}
std::ostream& operator<<(std::ostream& os, const vmime::mailbox& mbox)
{
os << "[mailbox: name=" << mbox.getName() << ", email=" << mbox.getEmail() << "]";
return (os);
}
std::ostream& operator<<(std::ostream& os, const vmime::mailboxGroup& group)
{
os << "[mailbox-group: name=" << group.getName() << ", list=[";
for (int i = 0 ; i < group.getMailboxCount() ; ++i)
{
if (i != 0)
os << ",";
os << *group.getMailboxAt(i);
}
os << "]]";
return (os);
}
std::ostream& operator<<(std::ostream& os, const vmime::addressList& list)
{
os << "[address-list: [";
for (int i = 0 ; i < list.getAddressCount() ; ++i)
{
const vmime::address& addr = *list.getAddressAt(i);
if (i != 0)
os << ",";
if (addr.isGroup())
{
const vmime::mailboxGroup& group =
dynamic_cast <const vmime::mailboxGroup&>(addr);
os << group;
}
else
{
const vmime::mailbox& mbox =
dynamic_cast <const vmime::mailbox&>(addr);
os << mbox;
}
}
os << "]]";
return (os);
}
std::ostream& operator<<(std::ostream& os, const vmime::datetime& d)
{
os << "[datetime: " << d.getYear() << "/" << d.getMonth() << "/" << d.getDay();
os << " " << d.getHour() << ":" << d.getMinute() << ":" << d.getSecond();
os << " #" << d.getZone() << "]";
return (os);
}
}

View File

@ -17,255 +17,238 @@
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
// //
#include "../lib/unit++/unit++.h" #include "tests/testUtils.hpp"
#include <iostream>
#include <ostream>
#include <sstream>
#include "vmime/vmime.hpp"
#include "vmime/platforms/posix/posixHandler.hpp"
#include "tests/parser/testUtils.hpp"
using namespace unitpp;
namespace #define VMIME_TEST_SUITE textTest
{ #define VMIME_TEST_SUITE_MODULE "Parser"
class textTest : public suite
VMIME_TEST_SUITE_BEGIN
VMIME_TEST_LIST_BEGIN
VMIME_TEST(testConstructors)
VMIME_TEST(testCopy)
VMIME_TEST(testNewFromString)
VMIME_TEST(testDisplayForm)
VMIME_TEST(testParse)
VMIME_TEST(testGenerate)
VMIME_TEST(testWordConstructors)
VMIME_TEST(testWordParse)
VMIME_TEST(testWordGenerate)
VMIME_TEST_LIST_END
void testConstructors()
{ {
void testConstructors() vmime::text t1;
{
vmime::text t1;
assert_eq("1.1", 0, t1.getWordCount()); VASSERT_EQ("1.1", 0, t1.getWordCount());
vmime::text t2("Test\xa9\xc3"); vmime::text t2("Test\xa9\xc3");
assert_eq("2.1", 1, t2.getWordCount()); VASSERT_EQ("2.1", 1, t2.getWordCount());
assert_eq("2.2", "Test\xa9\xc3", t2.getWordAt(0)->getBuffer()); VASSERT_EQ("2.2", "Test\xa9\xc3", t2.getWordAt(0)->getBuffer());
assert_eq("2.3", vmime::charset::getLocaleCharset(), t2.getWordAt(0)->getCharset()); VASSERT_EQ("2.3", vmime::charset::getLocaleCharset(), t2.getWordAt(0)->getCharset());
vmime::text t3("Test\xa9\xc3", vmime::charset(vmime::charsets::ISO8859_13)); vmime::text t3("Test\xa9\xc3", vmime::charset(vmime::charsets::ISO8859_13));
assert_eq("3.1", 1, t3.getWordCount()); VASSERT_EQ("3.1", 1, t3.getWordCount());
assert_eq("3.2", "Test\xa9\xc3", t3.getWordAt(0)->getBuffer()); VASSERT_EQ("3.2", "Test\xa9\xc3", t3.getWordAt(0)->getBuffer());
assert_eq("3.3", vmime::charset(vmime::charsets::ISO8859_13), t3.getWordAt(0)->getCharset()); VASSERT_EQ("3.3", vmime::charset(vmime::charsets::ISO8859_13), t3.getWordAt(0)->getCharset());
vmime::word w1("Test", vmime::charset(vmime::charsets::UTF_8)); vmime::word w1("Test", vmime::charset(vmime::charsets::UTF_8));
vmime::text t4(w1); vmime::text t4(w1);
assert_eq("4.1", 1, t4.getWordCount()); VASSERT_EQ("4.1", 1, t4.getWordCount());
assert_eq("4.2", w1.getBuffer(), t4.getWordAt(0)->getBuffer()); VASSERT_EQ("4.2", w1.getBuffer(), t4.getWordAt(0)->getBuffer());
assert_eq("4.3", w1.getCharset(), t4.getWordAt(0)->getCharset()); VASSERT_EQ("4.3", w1.getCharset(), t4.getWordAt(0)->getCharset());
vmime::word w2("Other", vmime::charset(vmime::charsets::US_ASCII)); vmime::word w2("Other", vmime::charset(vmime::charsets::US_ASCII));
t4.appendWord(vmime::create <vmime::word>(w2)); t4.appendWord(vmime::create <vmime::word>(w2));
vmime::text t5(t4); vmime::text t5(t4);
assert_eq("5.1", 2, t5.getWordCount()); VASSERT_EQ("5.1", 2, t5.getWordCount());
assert_eq("5.2", w1.getBuffer(), t5.getWordAt(0)->getBuffer()); VASSERT_EQ("5.2", w1.getBuffer(), t5.getWordAt(0)->getBuffer());
assert_eq("5.3", w1.getCharset(), t5.getWordAt(0)->getCharset()); VASSERT_EQ("5.3", w1.getCharset(), t5.getWordAt(0)->getCharset());
assert_eq("5.4", w2.getBuffer(), t5.getWordAt(1)->getBuffer()); VASSERT_EQ("5.4", w2.getBuffer(), t5.getWordAt(1)->getBuffer());
assert_eq("5.5", w2.getCharset(), t5.getWordAt(1)->getCharset()); VASSERT_EQ("5.5", w2.getCharset(), t5.getWordAt(1)->getCharset());
} }
void testCopy() void testCopy()
{ {
vmime::text t1("Test: \xa9\xc3"); vmime::text t1("Test: \xa9\xc3");
assert_true("operator==", t1 == t1); VASSERT("operator==", t1 == t1);
assert_true("clone", *vmime::clone(t1) == t1); VASSERT("clone", *vmime::clone(t1) == t1);
vmime::text t2; vmime::text t2;
t2.copyFrom(t1); t2.copyFrom(t1);
assert_true("copyFrom", t1 == t2); VASSERT("copyFrom", t1 == t2);
} }
void testNewFromString() void testNewFromString()
{ {
vmime::string s1 = "only ASCII characters"; vmime::string s1 = "only ASCII characters";
vmime::charset c1("test"); vmime::charset c1("test");
vmime::text t1; vmime::text t1;
t1.createFromString(s1, c1); t1.createFromString(s1, c1);
assert_eq("1.1", 1, t1.getWordCount()); VASSERT_EQ("1.1", 1, t1.getWordCount());
assert_eq("1.2", s1, t1.getWordAt(0)->getBuffer()); VASSERT_EQ("1.2", s1, t1.getWordAt(0)->getBuffer());
assert_eq("1.3", vmime::charset(vmime::charsets::US_ASCII), t1.getWordAt(0)->getCharset()); VASSERT_EQ("1.3", vmime::charset(vmime::charsets::US_ASCII), t1.getWordAt(0)->getCharset());
vmime::string s2_1 = "some ASCII characters and special chars: "; vmime::string s2_1 = "some ASCII characters and special chars: ";
vmime::string s2_2 = "\xf1\xf2\xf3\xf4 "; vmime::string s2_2 = "\xf1\xf2\xf3\xf4 ";
vmime::string s2_3 = "and then more ASCII chars."; vmime::string s2_3 = "and then more ASCII chars.";
vmime::string s2 = s2_1 + s2_2 + s2_3; vmime::string s2 = s2_1 + s2_2 + s2_3;
vmime::charset c2("test"); vmime::charset c2("test");
vmime::text t2; vmime::text t2;
t2.createFromString(s2, c2); t2.createFromString(s2, c2);
assert_eq("2.1", 3, t2.getWordCount()); VASSERT_EQ("2.1", 3, t2.getWordCount());
assert_eq("2.2", s2_1, t2.getWordAt(0)->getBuffer()); VASSERT_EQ("2.2", s2_1, t2.getWordAt(0)->getBuffer());
assert_eq("2.3", vmime::charset(vmime::charsets::US_ASCII), t2.getWordAt(0)->getCharset()); VASSERT_EQ("2.3", vmime::charset(vmime::charsets::US_ASCII), t2.getWordAt(0)->getCharset());
assert_eq("2.4", s2_2, t2.getWordAt(1)->getBuffer()); VASSERT_EQ("2.4", s2_2, t2.getWordAt(1)->getBuffer());
assert_eq("2.5", c2, t2.getWordAt(1)->getCharset()); VASSERT_EQ("2.5", c2, t2.getWordAt(1)->getCharset());
assert_eq("2.6", s2_3, t2.getWordAt(2)->getBuffer()); VASSERT_EQ("2.6", s2_3, t2.getWordAt(2)->getBuffer());
assert_eq("2.7", vmime::charset(vmime::charsets::US_ASCII), t2.getWordAt(2)->getCharset()); VASSERT_EQ("2.7", vmime::charset(vmime::charsets::US_ASCII), t2.getWordAt(2)->getCharset());
} }
static const vmime::string parseText(const vmime::string& buffer) static const vmime::string parseText(const vmime::string& buffer)
{ {
vmime::text t; vmime::text t;
t.parse(buffer); t.parse(buffer);
std::ostringstream oss; std::ostringstream oss;
oss << t; oss << t;
return (oss.str()); return (oss.str());
} }
void testParse() void testParse()
{ {
// From RFC-2047 // From RFC-2047
assert_eq("1", "[text: [[word: charset=US-ASCII, buffer=Keith Moore]]]", VASSERT_EQ("1", "[text: [[word: charset=US-ASCII, buffer=Keith Moore]]]",
parseText("=?US-ASCII?Q?Keith_Moore?=")); parseText("=?US-ASCII?Q?Keith_Moore?="));
assert_eq("2", "[text: [[word: charset=ISO-8859-1, buffer=Keld J\xf8rn Simonsen]]]", VASSERT_EQ("2", "[text: [[word: charset=ISO-8859-1, buffer=Keld J\xf8rn Simonsen]]]",
parseText("=?ISO-8859-1?Q?Keld_J=F8rn_Simonsen?=")); parseText("=?ISO-8859-1?Q?Keld_J=F8rn_Simonsen?="));
assert_eq("3", "[text: [[word: charset=ISO-8859-1, buffer=Andr\xe9]," \ VASSERT_EQ("3", "[text: [[word: charset=ISO-8859-1, buffer=Andr\xe9]," \
"[word: charset=us-ascii, buffer= Pirard]]]", "[word: charset=us-ascii, buffer= Pirard]]]",
parseText("=?ISO-8859-1?Q?Andr=E9?= Pirard")); parseText("=?ISO-8859-1?Q?Andr=E9?= Pirard"));
assert_eq("4", "[text: [[word: charset=ISO-8859-1, buffer=If you can read this yo]," \ VASSERT_EQ("4", "[text: [[word: charset=ISO-8859-1, buffer=If you can read this yo]," \
"[word: charset=ISO-8859-2, buffer=u understand the example.]]]", "[word: charset=ISO-8859-2, buffer=u understand the example.]]]",
parseText("=?ISO-8859-1?B?SWYgeW91IGNhbiByZWFkIHRoaXMgeW8=?=\r\n " \ parseText("=?ISO-8859-1?B?SWYgeW91IGNhbiByZWFkIHRoaXMgeW8=?=\r\n " \
"=?ISO-8859-2?B?dSB1bmRlcnN0YW5kIHRoZSBleGFtcGxlLg==?=")); "=?ISO-8859-2?B?dSB1bmRlcnN0YW5kIHRoZSBleGFtcGxlLg==?="));
// Bugfix: in "=?charset?q?=XX=YY?=", the "?=" finish // Bugfix: in "=?charset?q?=XX=YY?=", the "?=" finish
// sequence was not correctly found (should be the one // sequence was not correctly found (should be the one
// after '=YY' and not the one after '?q'). // after '=YY' and not the one after '?q').
assert_eq("5", "[text: [[word: charset=abc, buffer=\xe9\xe9]]]", VASSERT_EQ("5", "[text: [[word: charset=abc, buffer=\xe9\xe9]]]",
parseText("=?abc?q?=E9=E9?=")); parseText("=?abc?q?=E9=E9?="));
// Question marks (?) in the middle of the string // Question marks (?) in the middle of the string
assert_eq("6", "[text: [[word: charset=iso-8859-1, buffer=Know wh\xe4t? It works!]]]", VASSERT_EQ("6", "[text: [[word: charset=iso-8859-1, buffer=Know wh\xe4t? It works!]]]",
parseText("=?iso-8859-1?Q?Know_wh=E4t?_It_works!?=")); parseText("=?iso-8859-1?Q?Know_wh=E4t?_It_works!?="));
// TODO: add more // TODO: add more
} }
void testGenerate() void testGenerate()
{ {
// TODO // TODO
} }
static const vmime::string getDisplayText(const vmime::text& t) static const vmime::string getDisplayText(const vmime::text& t)
{ {
vmime::string res; vmime::string res;
for (int i = 0 ; i < t.getWordCount() ; ++i) for (int i = 0 ; i < t.getWordCount() ; ++i)
res += t.getWordAt(i)->getBuffer(); res += t.getWordAt(i)->getBuffer();
return res; return res;
} }
void testDisplayForm() void testDisplayForm()
{ {
#define DISPLAY_FORM(x) getDisplayText(*vmime::text::decodeAndUnfold(x)) #define DISPLAY_FORM(x) getDisplayText(*vmime::text::decodeAndUnfold(x))
// From RFC-2047 // From RFC-2047
assert_eq("1", "a", DISPLAY_FORM("=?ISO-8859-1?Q?a?=")); VASSERT_EQ("1", "a", DISPLAY_FORM("=?ISO-8859-1?Q?a?="));
assert_eq("2", "a b", DISPLAY_FORM("=?ISO-8859-1?Q?a?= b")); VASSERT_EQ("2", "a b", DISPLAY_FORM("=?ISO-8859-1?Q?a?= b"));
assert_eq("3", "ab", DISPLAY_FORM("=?ISO-8859-1?Q?a?= =?ISO-8859-1?Q?b?=")); VASSERT_EQ("3", "ab", DISPLAY_FORM("=?ISO-8859-1?Q?a?= =?ISO-8859-1?Q?b?="));
assert_eq("4", "ab", DISPLAY_FORM("=?ISO-8859-1?Q?a?= \t =?ISO-8859-1?Q?b?=")); VASSERT_EQ("4", "ab", DISPLAY_FORM("=?ISO-8859-1?Q?a?= \t =?ISO-8859-1?Q?b?="));
assert_eq("5", "ab", DISPLAY_FORM("=?ISO-8859-1?Q?a?= \r\n \t =?ISO-8859-1?Q?b?=")); VASSERT_EQ("5", "ab", DISPLAY_FORM("=?ISO-8859-1?Q?a?= \r\n \t =?ISO-8859-1?Q?b?="));
assert_eq("6", "a b", DISPLAY_FORM("=?ISO-8859-1?Q?a_b?=")); VASSERT_EQ("6", "a b", DISPLAY_FORM("=?ISO-8859-1?Q?a_b?="));
assert_eq("7", "a b", DISPLAY_FORM("=?ISO-8859-1?Q?a?= =?ISO-8859-2?Q?_b?=")); VASSERT_EQ("7", "a b", DISPLAY_FORM("=?ISO-8859-1?Q?a?= =?ISO-8859-2?Q?_b?="));
// Some more tests... // Some more tests...
assert_eq("8", "a b", DISPLAY_FORM(" a =?ISO-8859-1?Q?b?= ")); VASSERT_EQ("8", "a b", DISPLAY_FORM(" a =?ISO-8859-1?Q?b?= "));
assert_eq("9", "a b ", DISPLAY_FORM(" \t =?ISO-8859-1?Q?a?= b ")); VASSERT_EQ("9", "a b ", DISPLAY_FORM(" \t =?ISO-8859-1?Q?a?= b "));
assert_eq("10", "a b", DISPLAY_FORM(" a\r\n\t b")); VASSERT_EQ("10", "a b", DISPLAY_FORM(" a\r\n\t b"));
#undef DISPLAY_FORM #undef DISPLAY_FORM
} }
void testWordConstructors() void testWordConstructors()
{ {
assert_eq("1.1", vmime::charset::getLocaleCharset(), vmime::word().getCharset()); VASSERT_EQ("1.1", vmime::charset::getLocaleCharset(), vmime::word().getCharset());
assert_eq("1.2", "", vmime::word().getBuffer()); VASSERT_EQ("1.2", "", vmime::word().getBuffer());
assert_eq("2.1", vmime::charset::getLocaleCharset(), vmime::word("foo").getCharset()); VASSERT_EQ("2.1", vmime::charset::getLocaleCharset(), vmime::word("foo").getCharset());
assert_eq("2.2", "foo", vmime::word("foo").getBuffer()); VASSERT_EQ("2.2", "foo", vmime::word("foo").getBuffer());
assert_eq("3.1", "bar", vmime::word("foo", vmime::charset("bar")).getCharset().getName()); VASSERT_EQ("3.1", "bar", vmime::word("foo", vmime::charset("bar")).getCharset().getName());
assert_eq("3.2", "foo", vmime::word("foo", vmime::charset("bar")).getBuffer()); VASSERT_EQ("3.2", "foo", vmime::word("foo", vmime::charset("bar")).getBuffer());
} }
void testWordParse() void testWordParse()
{ {
// Simple encoded word // Simple encoded word
vmime::word w1; vmime::word w1;
w1.parse("=?foo?q?bar=E9 baz?="); w1.parse("=?foo?q?bar=E9 baz?=");
assert_eq("1.1", "foo", w1.getCharset().getName()); VASSERT_EQ("1.1", "foo", w1.getCharset().getName());
assert_eq("1.2", "bar\xe9 baz", w1.getBuffer()); VASSERT_EQ("1.2", "bar\xe9 baz", w1.getBuffer());
// Unencoded text // Unencoded text
vmime::word w2; vmime::word w2;
w2.parse(" foo bar \tbaz..."); w2.parse(" foo bar \tbaz...");
assert_eq("2.1", vmime::charset(vmime::charsets::US_ASCII), w2.getCharset()); VASSERT_EQ("2.1", vmime::charset(vmime::charsets::US_ASCII), w2.getCharset());
assert_eq("2.2", " foo bar \tbaz...", w2.getBuffer()); VASSERT_EQ("2.2", " foo bar \tbaz...", w2.getBuffer());
// Malformed word // Malformed word
vmime::word w3; vmime::word w3;
w3.parse("=?foo bar"); w3.parse("=?foo bar");
assert_eq("3.1", vmime::charset(vmime::charsets::US_ASCII), w3.getCharset()); VASSERT_EQ("3.1", vmime::charset(vmime::charsets::US_ASCII), w3.getCharset());
assert_eq("3.2", "=?foo bar", w3.getBuffer()); VASSERT_EQ("3.2", "=?foo bar", w3.getBuffer());
// Unknown encoding // Unknown encoding
vmime::word w4; vmime::word w4;
w4.parse("=?whatever?not_q_or_b?whatever?="); w4.parse("=?whatever?not_q_or_b?whatever?=");
assert_eq("4.1", vmime::charset(vmime::charsets::US_ASCII), w4.getCharset()); VASSERT_EQ("4.1", vmime::charset(vmime::charsets::US_ASCII), w4.getCharset());
assert_eq("4.2", "=?whatever?not_q_or_b?whatever?=", w4.getBuffer()); VASSERT_EQ("4.2", "=?whatever?not_q_or_b?whatever?=", w4.getBuffer());
} }
void testWordGenerate() void testWordGenerate()
{ {
assert_eq("1", "=?foo?Q?bar=E9_baz?=", VASSERT_EQ("1", "=?foo?Q?bar=E9_baz?=",
vmime::word("bar\xe9 baz", vmime::charset("foo")).generate()); vmime::word("bar\xe9 baz", vmime::charset("foo")).generate());
assert_eq("2", "=?foo?B?8fLz9PU=?=", VASSERT_EQ("2", "=?foo?B?8fLz9PU=?=",
vmime::word("\xf1\xf2\xf3\xf4\xf5", vmime::charset("foo")).generate()); vmime::word("\xf1\xf2\xf3\xf4\xf5", vmime::charset("foo")).generate());
} }
public: VMIME_TEST_SUITE_END
textTest() : suite("vmime::text")
{
vmime::platformDependant::setHandler<vmime::platforms::posix::posixHandler>();
add("Constructors", testcase(this, "Constructors", &textTest::testConstructors));
add("Copy", testcase(this, "Copy", &textTest::testCopy));
add("NewFromString", testcase(this, "NewFromString", &textTest::testNewFromString));
add("DisplayForm", testcase(this, "DisplayForm", &textTest::testDisplayForm));
add("Parse", testcase(this, "Parse", &textTest::testParse));
add("Generate", testcase(this, "Generate", &textTest::testGenerate));
add("WordConstructors", testcase(this, "WordConstructors", &textTest::testWordConstructors));
add("WordParse", testcase(this, "WordParse", &textTest::testWordParse));
add("WordGenerate", testcase(this, "WordGenerate", &textTest::testWordGenerate));
suite::main().add("vmime::text", this);
}
};
textTest* theTest = new textTest();
}

54
tests/testRunner.cpp Normal file
View File

@ -0,0 +1,54 @@
//
// VMime library (http://www.vmime.org)
// Copyright (C) 2002-2005 Vincent Richard <vincent@vincent-richard.net>
//
// 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 2 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, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//
#include <cppunit/XmlOutputter.h>
#include <cppunit/extensions/TestFactoryRegistry.h>
#include <cppunit/ui/text/TestRunner.h>
#include "vmime/vmime.hpp"
#include "vmime/platforms/posix/posixHandler.hpp"
int main(int argc, char* argv[])
{
// VMime initialization
vmime::platformDependant::setHandler<vmime::platforms::posix::posixHandler>();
// Get the top level suite from the registry
CppUnit::Test* suite = NULL;
if (argc > 1)
suite = CppUnit::TestFactoryRegistry::getRegistry(argv[1]).makeTest();
else
suite = CppUnit::TestFactoryRegistry::getRegistry().makeTest();
// Adds the test to the list of test to run
CppUnit::TextUi::TestRunner runner;
runner.addTest(suite);
// Change the default outputter to a compiler error format outputter
// runner.setOutputter(new CppUnit::XmlOutputter(&runner.result(), std::cerr));
// Run the tests
const bool wasSucessful = runner.run();
// Return error code 1 if the one of test failed
return wasSucessful ? 0 : 1;
}

182
tests/testUtils.hpp Normal file
View File

@ -0,0 +1,182 @@
//
// VMime library (http://www.vmime.org)
// Copyright (C) 2002-2005 Vincent Richard <vincent@vincent-richard.net>
//
// 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 2 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, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//
#include <ostream>
#include <iostream>
#include <sstream>
#include <vector>
// VMime
#include "vmime/vmime.hpp"
// CppUnit
#include <cppunit/TestAssert.h>
#include <cppunit/extensions/HelperMacros.h>
#define VASSERT(msg, cond) \
CPPUNIT_ASSERT_MESSAGE(std::string(msg), cond)
#define VASSERT_TRUE(msg, cond) \
VASSERT(msg, cond)
#define VASSERT_FALSE(msg, cond) \
VASSERT(!(msg, cond))
#define VASSERT_EQ(msg, expected, actual) \
CPPUNIT_ASSERT_EQUAL_MESSAGE(std::string(msg), expected, actual)
#define VASSERT_THROW(msg, expression, exceptionType) \
CPPUNIT_ASSERT_THROW(expression, exceptionType)
#define VASSERT_NO_THROW(msg, expression) \
CPPUNIT_ASSERT_NO_THROW(expression)
#define VMIME_TEST_SUITE_BEGIN \
class VMIME_TEST_SUITE : public CppUnit::TestFixture { public:
#define VMIME_TEST_SUITE_END \
}; \
\
static CppUnit::AutoRegisterSuite <VMIME_TEST_SUITE>(autoRegisterRegistry1); \
static CppUnit::AutoRegisterSuite <VMIME_TEST_SUITE>(autoRegisterRegistry2)(VMIME_TEST_SUITE_MODULE);
#define VMIME_TEST_LIST_BEGIN CPPUNIT_TEST_SUITE(VMIME_TEST_SUITE);
#define VMIME_TEST_LIST_END CPPUNIT_TEST_SUITE_END();
#define VMIME_TEST(name) CPPUNIT_TEST(name);
namespace CppUnit
{
// Work-around for comparing 'std::string' against 'char*'
inline void assertEquals(const char* expected, const std::string actual,
SourceLine sourceLine, const std::string &message)
{
assertEquals(std::string(expected), actual, sourceLine, message);
}
template <typename X, typename Y>
void assertEquals(const X expected, const Y actual,
SourceLine sourceLine, const std::string &message)
{
assertEquals(static_cast <Y>(expected), actual, sourceLine, message);
}
}
namespace std
{
inline std::ostream& operator<<(std::ostream& os, const vmime::charset& ch)
{
os << "[charset: " << ch.getName() << "]";
return (os);
}
inline std::ostream& operator<<(std::ostream& os, const vmime::text& txt)
{
os << "[text: [";
for (int i = 0 ; i < txt.getWordCount() ; ++i)
{
const vmime::word& w = *txt.getWordAt(i);
if (i != 0)
os << ",";
os << "[word: charset=" << w.getCharset().getName() << ", buffer=" << w.getBuffer() << "]";
}
os << "]]";
return (os);
}
inline std::ostream& operator<<(std::ostream& os, const vmime::mailbox& mbox)
{
os << "[mailbox: name=" << mbox.getName() << ", email=" << mbox.getEmail() << "]";
return (os);
}
inline std::ostream& operator<<(std::ostream& os, const vmime::mailboxGroup& group)
{
os << "[mailbox-group: name=" << group.getName() << ", list=[";
for (int i = 0 ; i < group.getMailboxCount() ; ++i)
{
if (i != 0)
os << ",";
os << *group.getMailboxAt(i);
}
os << "]]";
return (os);
}
inline std::ostream& operator<<(std::ostream& os, const vmime::addressList& list)
{
os << "[address-list: [";
for (int i = 0 ; i < list.getAddressCount() ; ++i)
{
const vmime::address& addr = *list.getAddressAt(i);
if (i != 0)
os << ",";
if (addr.isGroup())
{
const vmime::mailboxGroup& group =
dynamic_cast <const vmime::mailboxGroup&>(addr);
os << group;
}
else
{
const vmime::mailbox& mbox =
dynamic_cast <const vmime::mailbox&>(addr);
os << mbox;
}
}
os << "]]";
return (os);
}
inline std::ostream& operator<<(std::ostream& os, const vmime::datetime& d)
{
os << "[datetime: " << d.getYear() << "/" << d.getMonth() << "/" << d.getDay();
os << " " << d.getHour() << ":" << d.getMinute() << ":" << d.getSecond();
os << " #" << d.getZone() << "]";
return (os);
}
}

View File

@ -17,274 +17,257 @@
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
// //
#include "../lib/unit++/unit++.h" #include "tests/testUtils.hpp"
#include <iostream>
#include <ostream>
#include <algorithm>
#include "vmime/vmime.hpp"
#include "vmime/platforms/posix/posixHandler.hpp"
#include "vmime/utility/filteredStream.hpp" #include "vmime/utility/filteredStream.hpp"
using namespace unitpp;
#define VMIME_TEST_SUITE filteredStreamTest
#define VMIME_TEST_SUITE_MODULE "Utility"
namespace VMIME_TEST_SUITE_BEGIN
{
class filteredStreamTest : public suite VMIME_TEST_LIST_BEGIN
VMIME_TEST(testDotFilteredInputStream)
VMIME_TEST(testDotFilteredOutputStream)
VMIME_TEST(testCRLFToLFFilteredOutputStream)
VMIME_TEST(testStopSequenceFilteredInputStream1)
VMIME_TEST(testStopSequenceFilteredInputStreamN_2)
VMIME_TEST(testStopSequenceFilteredInputStreamN_3)
VMIME_TEST_LIST_END
class chunkInputStream : public vmime::utility::inputStream
{ {
class chunkInputStream : public vmime::utility::inputStream private:
{
private:
std::vector <std::string> m_chunks; std::vector <std::string> m_chunks;
std::vector <std::string>::size_type m_index; std::vector <std::string>::size_type m_index;
public:
chunkInputStream() : m_index(0) { }
void addChunk(const std::string& chunk) { m_chunks.push_back(chunk); }
const bool eof() const { return (m_index >= m_chunks.size()); }
void reset() { m_index = 0; }
const size_type read(value_type* const data, const size_type /* count */)
{
if (eof())
return 0;
const std::string chunk = m_chunks[m_index];
// Warning: 'count' should be larger than chunk length.
// This is OK for our tests.
std::copy(chunk.begin(), chunk.end(), data);
++m_index;
return chunk.length();
}
const size_type skip(const size_type /* count */)
{
// Not supported
return 0;
}
};
const std::string readWhole(vmime::utility::inputStream& is)
{
vmime::utility::stream::value_type buffer[256];
std::string whole;
while (!is.eof())
{
const vmime::utility::stream::size_type read =
is.read(buffer, sizeof(buffer));
whole += std::string(buffer, read);
}
return (whole);
}
// dotFilteredInputStream
void testDotFilteredInputStreamHelper
(const std::string& number, const std::string& expected,
const std::string& c1, const std::string& c2 = "",
const std::string& c3 = "", const std::string& c4 = "")
{
chunkInputStream cis;
cis.addChunk(c1);
if (!c2.empty()) cis.addChunk(c2);
if (!c3.empty()) cis.addChunk(c3);
if (!c4.empty()) cis.addChunk(c4);
vmime::utility::dotFilteredInputStream is(cis);
std::ostringstream oss;
vmime::utility::outputStreamAdapter os(oss);
vmime::utility::bufferedStreamCopy(is, os);
assert_eq(number, expected, oss.str());
}
void testDotFilteredInputStream()
{
testDotFilteredInputStreamHelper("1", "foo\n.bar", "foo\n..bar");
testDotFilteredInputStreamHelper("2", "foo\n.bar", "foo\n", "..bar");
testDotFilteredInputStreamHelper("3", "foo\n.bar", "foo\n.", ".bar");
testDotFilteredInputStreamHelper("4", "foo\n.bar", "foo\n..", "bar");
testDotFilteredInputStreamHelper("5", "foo\n.bar", "foo\n", ".", ".bar");
testDotFilteredInputStreamHelper("6", "foo\n.bar", "foo\n", ".", ".", "bar");
}
// dotFilteredOutputStream
// CRLFToLFFilteredOutputStream
template <typename FILTER>
void testFilteredOutputStreamHelper
(const std::string& number, const std::string& expected,
const std::string& c1, const std::string& c2 = "",
const std::string& c3 = "", const std::string& c4 = "")
{
std::ostringstream oss;
vmime::utility::outputStreamAdapter os(oss);
FILTER fos(os);
fos.write(c1.data(), c1.length());
if (!c2.empty()) fos.write(c2.data(), c2.length());
if (!c3.empty()) fos.write(c3.data(), c3.length());
if (!c4.empty()) fos.write(c4.data(), c4.length());
assert_eq(number, expected, oss.str());
}
void testDotFilteredOutputStream()
{
typedef vmime::utility::dotFilteredOutputStream FILTER;
testFilteredOutputStreamHelper<FILTER>("1", "foo\n..bar", "foo\n.bar");
testFilteredOutputStreamHelper<FILTER>("2", "foo\n..bar", "foo\n", ".bar");
testFilteredOutputStreamHelper<FILTER>("3", "foo\n..bar", "foo", "\n.bar");
testFilteredOutputStreamHelper<FILTER>("4", "foo\n..bar", "foo", "\n", ".bar");
testFilteredOutputStreamHelper<FILTER>("5", "foo\n..bar", "foo", "\n", ".", "bar");
}
void testCRLFToLFFilteredOutputStream()
{
typedef vmime::utility::CRLFToLFFilteredOutputStream FILTER;
testFilteredOutputStreamHelper<FILTER>("1", "foo\nbar", "foo\r\nbar");
testFilteredOutputStreamHelper<FILTER>("2", "foo\nbar", "foo\r\n", "bar");
testFilteredOutputStreamHelper<FILTER>("3", "foo\nbar", "foo\r", "\nbar");
testFilteredOutputStreamHelper<FILTER>("4", "foo\nbar", "foo", "\r\nbar");
testFilteredOutputStreamHelper<FILTER>("5", "foo\nbar", "foo", "\r", "\nbar");
testFilteredOutputStreamHelper<FILTER>("6", "foo\nbar", "foo", "\r", "\n", "bar");
}
// stopSequenceFilteredInputStream
template <int N>
void testStopSequenceFISHelper
(const std::string& number, const std::string& sequence,
const std::string& expected, const std::string& c1,
const std::string& c2 = "", const std::string& c3 = "",
const std::string& c4 = "", const std::string& c5 = "")
{
chunkInputStream cis;
cis.addChunk(c1);
if (!c2.empty()) cis.addChunk(c2);
if (!c3.empty()) cis.addChunk(c3);
if (!c4.empty()) cis.addChunk(c4);
if (!c5.empty()) cis.addChunk(c5);
vmime::utility::stopSequenceFilteredInputStream <N> is(cis, sequence.data());
assert_eq(number, expected, readWhole(is));
}
void testStopSequenceFilteredInputStream1()
{
testStopSequenceFISHelper <1>("1", "x", "foo", "fooxbar");
testStopSequenceFISHelper <1>("2", "x", "foo", "foox", "bar");
testStopSequenceFISHelper <1>("3", "x", "foo", "foo", "x", "bar");
testStopSequenceFISHelper <1>("4", "x", "foo", "fo", "o", "x", "bar");
testStopSequenceFISHelper <1>("5", "x", "foo", "fo", "o", "x", "b", "ar");
testStopSequenceFISHelper <1>("6", "x", "foobar", "fo", "o", "b", "ar");
testStopSequenceFISHelper <1>("7", "x", "foobar", "foo", "bar");
testStopSequenceFISHelper <1>("8", "x", "foobar", "foo", "b", "ar");
testStopSequenceFISHelper <1>("9", "x", "foobar", "foobar");
testStopSequenceFISHelper <1>("10", "x", "foobar", "foobarx");
testStopSequenceFISHelper <1>("11", "x", "", "");
testStopSequenceFISHelper <1>("12", "x", "", "x");
testStopSequenceFISHelper <1>("13", "x", "", "", "x");
}
void testStopSequenceFilteredInputStreamN_2()
{
testStopSequenceFISHelper <2>("1", "xy", "foo", "fooxybar");
testStopSequenceFISHelper <2>("2", "xy", "foo", "foox", "ybar");
testStopSequenceFISHelper <2>("3", "xy", "foo", "foox", "y", "bar");
testStopSequenceFISHelper <2>("4", "xy", "foo", "foo", "x", "ybar");
testStopSequenceFISHelper <2>("5", "xy", "foo", "foo", "xy", "bar");
testStopSequenceFISHelper <2>("6", "xy", "foo", "foo", "x", "y", "bar");
testStopSequenceFISHelper <2>("7", "xy", "fooxbar", "foox", "bar");
testStopSequenceFISHelper <2>("8", "xy", "fooxbar", "foo", "xbar");
testStopSequenceFISHelper <2>("9", "xy", "fooxbar", "foo", "x", "bar");
testStopSequenceFISHelper <2>("10", "xy", "foobarx", "foo", "barx");
testStopSequenceFISHelper <2>("11", "xy", "foobar", "foobarxy");
testStopSequenceFISHelper <2>("12", "xy", "foobar", "foo", "barxy");
testStopSequenceFISHelper <2>("13", "xy", "foobar", "foo", "bar", "xy");
testStopSequenceFISHelper <2>("14", "xy", "", "");
testStopSequenceFISHelper <2>("15", "xy", "x", "x");
testStopSequenceFISHelper <2>("16", "xy", "", "xy");
testStopSequenceFISHelper <2>("17", "xy", "", "x", "y");
}
void testStopSequenceFilteredInputStreamN_3()
{
testStopSequenceFISHelper <3>("1", "xyz", "foo", "fooxyzbar");
testStopSequenceFISHelper <3>("2", "xyz", "foo", "foox", "yzbar");
testStopSequenceFISHelper <3>("3", "xyz", "foo", "foox", "y", "zbar");
testStopSequenceFISHelper <3>("4", "xyz", "foo", "foox", "yz", "bar");
testStopSequenceFISHelper <3>("5", "xyz", "foo", "foo", "xyz", "bar");
testStopSequenceFISHelper <3>("6", "xyz", "foo", "foo", "xy", "zbar");
testStopSequenceFISHelper <3>("7", "xyz", "foo", "foo", "x", "y", "zbar");
testStopSequenceFISHelper <3>("8", "xyz", "foo", "foo", "x", "y", "z", "bar");
testStopSequenceFISHelper <3>("9", "xyz", "foo", "fooxy", "z", "bar");
testStopSequenceFISHelper <3>("10", "xyz", "fooxybar", "foox", "y", "bar");
testStopSequenceFISHelper <3>("11", "xyz", "fooxybar", "fooxy", "bar");
testStopSequenceFISHelper <3>("12", "xyz", "fooxybar", "fo", "ox", "y", "bar");
testStopSequenceFISHelper <3>("13", "xyz", "fooxybar", "fo", "o", "x", "y", "bar");
testStopSequenceFISHelper <3>("14", "xyz", "fooxybar", "foo", "x", "ybar");
testStopSequenceFISHelper <3>("15", "xyz", "fooxybar", "foo", "xybar");
testStopSequenceFISHelper <3>("16", "xyz", "xfoxoxybxar", "xfoxo", "xybxar");
testStopSequenceFISHelper <3>("17", "xyz", "xfoxoxybxarx", "xfoxo", "xybxarx");
testStopSequenceFISHelper <3>("18", "xyz", "xfoxoxybxarxy", "xfoxo", "xybxarxy");
testStopSequenceFISHelper <3>("19", "xyz", "", "");
testStopSequenceFISHelper <3>("20", "xyz", "x", "x");
testStopSequenceFISHelper <3>("21", "xyz", "xy", "xy");
testStopSequenceFISHelper <3>("22", "xyz", "", "xyz");
testStopSequenceFISHelper <3>("23", "xyz", "", "x", "yz");
testStopSequenceFISHelper <3>("24", "xyz", "", "x", "y", "z");
}
public: public:
filteredStreamTest() : suite("vmime::utility::filteredStream") chunkInputStream() : m_index(0) { }
void addChunk(const std::string& chunk) { m_chunks.push_back(chunk); }
const bool eof() const { return (m_index >= m_chunks.size()); }
void reset() { m_index = 0; }
const size_type read(value_type* const data, const size_type /* count */)
{ {
// VMime initialization if (eof())
vmime::platformDependant::setHandler<vmime::platforms::posix::posixHandler>(); return 0;
add("dotFilteredInputStream", testcase(this, "dotFilteredInputStream", &filteredStreamTest::testDotFilteredInputStream)); const std::string chunk = m_chunks[m_index];
add("dotFilteredOutputStream", testcase(this, "dotFilteredOutputStream", &filteredStreamTest::testDotFilteredOutputStream));
add("CRLFToLFFilteredOutputStream", testcase(this, "CRLFToLFFilteredOutputStream", &filteredStreamTest::testCRLFToLFFilteredOutputStream));
add("stopSequenceFilteredInputStream1", testcase(this, "stopSequenceFilteredInputStream1", &filteredStreamTest::testStopSequenceFilteredInputStream1));
add("stopSequenceFilteredInputStreamN_2", testcase(this, "stopSequenceFilteredInputStreamN_2", &filteredStreamTest::testStopSequenceFilteredInputStreamN_2));
add("stopSequenceFilteredInputStreamN_3", testcase(this, "stopSequenceFilteredInputStreamN_3", &filteredStreamTest::testStopSequenceFilteredInputStreamN_3));
suite::main().add("vmime::utility::filteredStream", this); // Warning: 'count' should be larger than chunk length.
// This is OK for our tests.
std::copy(chunk.begin(), chunk.end(), data);
++m_index;
return chunk.length();
} }
const size_type skip(const size_type /* count */)
{
// Not supported
return 0;
}
}; };
filteredStreamTest* theTest = new filteredStreamTest();
} const std::string readWhole(vmime::utility::inputStream& is)
{
vmime::utility::stream::value_type buffer[256];
std::string whole;
while (!is.eof())
{
const vmime::utility::stream::size_type read =
is.read(buffer, sizeof(buffer));
whole += std::string(buffer, read);
}
return (whole);
}
// dotFilteredInputStream
void testDotFilteredInputStreamHelper
(const std::string& number, const std::string& expected,
const std::string& c1, const std::string& c2 = "",
const std::string& c3 = "", const std::string& c4 = "")
{
chunkInputStream cis;
cis.addChunk(c1);
if (!c2.empty()) cis.addChunk(c2);
if (!c3.empty()) cis.addChunk(c3);
if (!c4.empty()) cis.addChunk(c4);
vmime::utility::dotFilteredInputStream is(cis);
std::ostringstream oss;
vmime::utility::outputStreamAdapter os(oss);
vmime::utility::bufferedStreamCopy(is, os);
VASSERT_EQ(number, expected, oss.str());
}
void testDotFilteredInputStream()
{
testDotFilteredInputStreamHelper("1", "foo\n.bar", "foo\n..bar");
testDotFilteredInputStreamHelper("2", "foo\n.bar", "foo\n", "..bar");
testDotFilteredInputStreamHelper("3", "foo\n.bar", "foo\n.", ".bar");
testDotFilteredInputStreamHelper("4", "foo\n.bar", "foo\n..", "bar");
testDotFilteredInputStreamHelper("5", "foo\n.bar", "foo\n", ".", ".bar");
testDotFilteredInputStreamHelper("6", "foo\n.bar", "foo\n", ".", ".", "bar");
}
// dotFilteredOutputStream
// CRLFToLFFilteredOutputStream
template <typename FILTER>
void testFilteredOutputStreamHelper
(const std::string& number, const std::string& expected,
const std::string& c1, const std::string& c2 = "",
const std::string& c3 = "", const std::string& c4 = "")
{
std::ostringstream oss;
vmime::utility::outputStreamAdapter os(oss);
FILTER fos(os);
fos.write(c1.data(), c1.length());
if (!c2.empty()) fos.write(c2.data(), c2.length());
if (!c3.empty()) fos.write(c3.data(), c3.length());
if (!c4.empty()) fos.write(c4.data(), c4.length());
VASSERT_EQ(number, expected, oss.str());
}
void testDotFilteredOutputStream()
{
typedef vmime::utility::dotFilteredOutputStream FILTER;
testFilteredOutputStreamHelper<FILTER>("1", "foo\n..bar", "foo\n.bar");
testFilteredOutputStreamHelper<FILTER>("2", "foo\n..bar", "foo\n", ".bar");
testFilteredOutputStreamHelper<FILTER>("3", "foo\n..bar", "foo", "\n.bar");
testFilteredOutputStreamHelper<FILTER>("4", "foo\n..bar", "foo", "\n", ".bar");
testFilteredOutputStreamHelper<FILTER>("5", "foo\n..bar", "foo", "\n", ".", "bar");
}
void testCRLFToLFFilteredOutputStream()
{
typedef vmime::utility::CRLFToLFFilteredOutputStream FILTER;
testFilteredOutputStreamHelper<FILTER>("1", "foo\nbar", "foo\r\nbar");
testFilteredOutputStreamHelper<FILTER>("2", "foo\nbar", "foo\r\n", "bar");
testFilteredOutputStreamHelper<FILTER>("3", "foo\nbar", "foo\r", "\nbar");
testFilteredOutputStreamHelper<FILTER>("4", "foo\nbar", "foo", "\r\nbar");
testFilteredOutputStreamHelper<FILTER>("5", "foo\nbar", "foo", "\r", "\nbar");
testFilteredOutputStreamHelper<FILTER>("6", "foo\nbar", "foo", "\r", "\n", "bar");
}
// stopSequenceFilteredInputStream
template <int N>
void testStopSequenceFISHelper
(const std::string& number, const std::string& sequence,
const std::string& expected, const std::string& c1,
const std::string& c2 = "", const std::string& c3 = "",
const std::string& c4 = "", const std::string& c5 = "")
{
chunkInputStream cis;
cis.addChunk(c1);
if (!c2.empty()) cis.addChunk(c2);
if (!c3.empty()) cis.addChunk(c3);
if (!c4.empty()) cis.addChunk(c4);
if (!c5.empty()) cis.addChunk(c5);
vmime::utility::stopSequenceFilteredInputStream <N> is(cis, sequence.data());
VASSERT_EQ(number, expected, readWhole(is));
}
void testStopSequenceFilteredInputStream1()
{
testStopSequenceFISHelper <1>("1", "x", "foo", "fooxbar");
testStopSequenceFISHelper <1>("2", "x", "foo", "foox", "bar");
testStopSequenceFISHelper <1>("3", "x", "foo", "foo", "x", "bar");
testStopSequenceFISHelper <1>("4", "x", "foo", "fo", "o", "x", "bar");
testStopSequenceFISHelper <1>("5", "x", "foo", "fo", "o", "x", "b", "ar");
testStopSequenceFISHelper <1>("6", "x", "foobar", "fo", "o", "b", "ar");
testStopSequenceFISHelper <1>("7", "x", "foobar", "foo", "bar");
testStopSequenceFISHelper <1>("8", "x", "foobar", "foo", "b", "ar");
testStopSequenceFISHelper <1>("9", "x", "foobar", "foobar");
testStopSequenceFISHelper <1>("10", "x", "foobar", "foobarx");
testStopSequenceFISHelper <1>("11", "x", "", "");
testStopSequenceFISHelper <1>("12", "x", "", "x");
testStopSequenceFISHelper <1>("13", "x", "", "", "x");
}
void testStopSequenceFilteredInputStreamN_2()
{
testStopSequenceFISHelper <2>("1", "xy", "foo", "fooxybar");
testStopSequenceFISHelper <2>("2", "xy", "foo", "foox", "ybar");
testStopSequenceFISHelper <2>("3", "xy", "foo", "foox", "y", "bar");
testStopSequenceFISHelper <2>("4", "xy", "foo", "foo", "x", "ybar");
testStopSequenceFISHelper <2>("5", "xy", "foo", "foo", "xy", "bar");
testStopSequenceFISHelper <2>("6", "xy", "foo", "foo", "x", "y", "bar");
testStopSequenceFISHelper <2>("7", "xy", "fooxbar", "foox", "bar");
testStopSequenceFISHelper <2>("8", "xy", "fooxbar", "foo", "xbar");
testStopSequenceFISHelper <2>("9", "xy", "fooxbar", "foo", "x", "bar");
testStopSequenceFISHelper <2>("10", "xy", "foobarx", "foo", "barx");
testStopSequenceFISHelper <2>("11", "xy", "foobar", "foobarxy");
testStopSequenceFISHelper <2>("12", "xy", "foobar", "foo", "barxy");
testStopSequenceFISHelper <2>("13", "xy", "foobar", "foo", "bar", "xy");
testStopSequenceFISHelper <2>("14", "xy", "", "");
testStopSequenceFISHelper <2>("15", "xy", "x", "x");
testStopSequenceFISHelper <2>("16", "xy", "", "xy");
testStopSequenceFISHelper <2>("17", "xy", "", "x", "y");
}
void testStopSequenceFilteredInputStreamN_3()
{
testStopSequenceFISHelper <3>("1", "xyz", "foo", "fooxyzbar");
testStopSequenceFISHelper <3>("2", "xyz", "foo", "foox", "yzbar");
testStopSequenceFISHelper <3>("3", "xyz", "foo", "foox", "y", "zbar");
testStopSequenceFISHelper <3>("4", "xyz", "foo", "foox", "yz", "bar");
testStopSequenceFISHelper <3>("5", "xyz", "foo", "foo", "xyz", "bar");
testStopSequenceFISHelper <3>("6", "xyz", "foo", "foo", "xy", "zbar");
testStopSequenceFISHelper <3>("7", "xyz", "foo", "foo", "x", "y", "zbar");
testStopSequenceFISHelper <3>("8", "xyz", "foo", "foo", "x", "y", "z", "bar");
testStopSequenceFISHelper <3>("9", "xyz", "foo", "fooxy", "z", "bar");
testStopSequenceFISHelper <3>("10", "xyz", "fooxybar", "foox", "y", "bar");
testStopSequenceFISHelper <3>("11", "xyz", "fooxybar", "fooxy", "bar");
testStopSequenceFISHelper <3>("12", "xyz", "fooxybar", "fo", "ox", "y", "bar");
testStopSequenceFISHelper <3>("13", "xyz", "fooxybar", "fo", "o", "x", "y", "bar");
testStopSequenceFISHelper <3>("14", "xyz", "fooxybar", "foo", "x", "ybar");
testStopSequenceFISHelper <3>("15", "xyz", "fooxybar", "foo", "xybar");
testStopSequenceFISHelper <3>("16", "xyz", "xfoxoxybxar", "xfoxo", "xybxar");
testStopSequenceFISHelper <3>("17", "xyz", "xfoxoxybxarx", "xfoxo", "xybxarx");
testStopSequenceFISHelper <3>("18", "xyz", "xfoxoxybxarxy", "xfoxo", "xybxarxy");
testStopSequenceFISHelper <3>("19", "xyz", "", "");
testStopSequenceFISHelper <3>("20", "xyz", "x", "x");
testStopSequenceFISHelper <3>("21", "xyz", "xy", "xy");
testStopSequenceFISHelper <3>("22", "xyz", "", "xyz");
testStopSequenceFISHelper <3>("23", "xyz", "", "x", "yz");
testStopSequenceFISHelper <3>("24", "xyz", "", "x", "y", "z");
}
VMIME_TEST_SUITE_END

View File

@ -17,96 +17,82 @@
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
// //
#include "../lib/unit++/unit++.h" #include "tests/testUtils.hpp"
#include <iostream>
#include <ostream>
#include "vmime/vmime.hpp"
#include "vmime/platforms/posix/posixHandler.hpp"
#include "vmime/utility/md5.hpp" #include "vmime/utility/md5.hpp"
using namespace unitpp;
#define VMIME_TEST_SUITE md5Test
#define VMIME_TEST_SUITE_MODULE "Utility"
namespace VMIME_TEST_SUITE_BEGIN
{
class md5Test : public suite VMIME_TEST_LIST_BEGIN
VMIME_TEST(testString)
VMIME_TEST(testUpdate)
VMIME_TEST_LIST_END
void testString()
{ {
void testString() // Test suites from RFC #1321
{ VASSERT_EQ("1", "d41d8cd98f00b204e9800998ecf8427e", vmime::utility::md5("").hex());
// Test suites from RFC #1321 VASSERT_EQ("2", "0cc175b9c0f1b6a831c399e269772661", vmime::utility::md5("a").hex());
assert_eq("1", "d41d8cd98f00b204e9800998ecf8427e", vmime::utility::md5("").hex()); VASSERT_EQ("3", "900150983cd24fb0d6963f7d28e17f72", vmime::utility::md5("abc").hex());
assert_eq("2", "0cc175b9c0f1b6a831c399e269772661", vmime::utility::md5("a").hex()); VASSERT_EQ("4", "f96b697d7cb7938d525a2f31aaf161d0", vmime::utility::md5("message digest").hex());
assert_eq("3", "900150983cd24fb0d6963f7d28e17f72", vmime::utility::md5("abc").hex()); VASSERT_EQ("5", "c3fcd3d76192e4007dfb496cca67e13b", vmime::utility::md5("abcdefghijklmnopqrstuvwxyz").hex());
assert_eq("4", "f96b697d7cb7938d525a2f31aaf161d0", vmime::utility::md5("message digest").hex()); VASSERT_EQ("6", "d174ab98d277d9f5a5611c2c9f419d9f", vmime::utility::md5("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789").hex());
assert_eq("5", "c3fcd3d76192e4007dfb496cca67e13b", vmime::utility::md5("abcdefghijklmnopqrstuvwxyz").hex()); VASSERT_EQ("7", "57edf4a22be3c955ac49da2e2107b67a", vmime::utility::md5("12345678901234567890123456789012345678901234567890123456789012345678901234567890").hex());
assert_eq("6", "d174ab98d277d9f5a5611c2c9f419d9f", vmime::utility::md5("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789").hex()); }
assert_eq("7", "57edf4a22be3c955ac49da2e2107b67a", vmime::utility::md5("12345678901234567890123456789012345678901234567890123456789012345678901234567890").hex());
}
void testUpdate() void testUpdate()
{ {
vmime::utility::md5 m1; vmime::utility::md5 m1;
m1.update(""); m1.update("");
assert_eq("1", "d41d8cd98f00b204e9800998ecf8427e", m1.hex()); VASSERT_EQ("1", "d41d8cd98f00b204e9800998ecf8427e", m1.hex());
vmime::utility::md5 m2; vmime::utility::md5 m2;
m2.update("a"); m2.update("a");
m2.update(""); m2.update("");
assert_eq("2", "0cc175b9c0f1b6a831c399e269772661", m2.hex()); VASSERT_EQ("2", "0cc175b9c0f1b6a831c399e269772661", m2.hex());
vmime::utility::md5 m3; vmime::utility::md5 m3;
m3.update("ab"); m3.update("ab");
m3.update("c"); m3.update("c");
assert_eq("3", "900150983cd24fb0d6963f7d28e17f72", m3.hex()); VASSERT_EQ("3", "900150983cd24fb0d6963f7d28e17f72", m3.hex());
vmime::utility::md5 m4; vmime::utility::md5 m4;
m4.update(""); m4.update("");
m4.update("message"); m4.update("message");
m4.update(" "); m4.update(" ");
m4.update("digest"); m4.update("digest");
assert_eq("4", "f96b697d7cb7938d525a2f31aaf161d0", m4.hex()); VASSERT_EQ("4", "f96b697d7cb7938d525a2f31aaf161d0", m4.hex());
vmime::utility::md5 m5; vmime::utility::md5 m5;
m5.update("abcd"); m5.update("abcd");
m5.update(""); m5.update("");
m5.update("efghijklmnop"); m5.update("efghijklmnop");
m5.update("qrstuvwx"); m5.update("qrstuvwx");
m5.update("yz"); m5.update("yz");
assert_eq("5", "c3fcd3d76192e4007dfb496cca67e13b", m5.hex()); VASSERT_EQ("5", "c3fcd3d76192e4007dfb496cca67e13b", m5.hex());
vmime::utility::md5 m6; vmime::utility::md5 m6;
m6.update("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz012"); m6.update("ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz012");
m6.update("345"); m6.update("345");
m6.update("6"); m6.update("6");
m6.update("7"); m6.update("7");
m6.update("89"); m6.update("89");
assert_eq("6", "d174ab98d277d9f5a5611c2c9f419d9f", m6.hex()); VASSERT_EQ("6", "d174ab98d277d9f5a5611c2c9f419d9f", m6.hex());
vmime::utility::md5 m7; vmime::utility::md5 m7;
m7.update("12345678901234567890123456789"); m7.update("12345678901234567890123456789");
m7.update("01234567890123456789012345678901"); m7.update("01234567890123456789012345678901");
m7.update("234567890123456789"); m7.update("234567890123456789");
m7.update(""); m7.update("");
m7.update("0"); m7.update("0");
assert_eq("7", "57edf4a22be3c955ac49da2e2107b67a", m7.hex()); VASSERT_EQ("7", "57edf4a22be3c955ac49da2e2107b67a", m7.hex());
} }
public: VMIME_TEST_SUITE_END
md5Test() : suite("vmime::utility::md5")
{
// VMime initialization
vmime::platformDependant::setHandler<vmime::platforms::posix::posixHandler>();
add("String", testcase(this, "String", &md5Test::testString));
add("Update", testcase(this, "Update", &md5Test::testUpdate));
suite::main().add("vmime::utility::md5", this);
}
};
md5Test* theTest = new md5Test();
}

View File

@ -17,301 +17,287 @@
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
// //
#include "../lib/unit++/unit++.h" #include "tests/testUtils.hpp"
#include <iostream>
#include <ostream>
#include "vmime/vmime.hpp"
#include "vmime/platforms/posix/posixHandler.hpp"
#include "vmime/utility/path.hpp" #include "vmime/utility/path.hpp"
using namespace unitpp;
#define VMIME_TEST_SUITE pathTest
#define VMIME_TEST_SUITE_MODULE "Utility"
namespace VMIME_TEST_SUITE_BEGIN
{
class pathTest : public suite VMIME_TEST_LIST_BEGIN
VMIME_TEST(testConstruct1)
VMIME_TEST(testConstruct2)
VMIME_TEST(testConstruct3)
VMIME_TEST(testConstruct4)
VMIME_TEST(testAppendComponent)
VMIME_TEST(testOperatorDiv1)
VMIME_TEST(testOperatorDiv2)
VMIME_TEST(testOperatorDivEqual1)
VMIME_TEST(testOperatorDivEqual2)
VMIME_TEST(testGetParent)
VMIME_TEST(testComparison)
VMIME_TEST(testGetLastComponent)
VMIME_TEST(testIsDirectParentOf)
VMIME_TEST(testIsParentOf)
VMIME_TEST(testRenameParent)
VMIME_TEST_LIST_END
typedef vmime::utility::path path;
typedef vmime::utility::path::component comp;
void testConstruct1()
{ {
typedef vmime::utility::path path; VASSERT_EQ("1", true, path().isEmpty());
typedef vmime::utility::path::component comp; VASSERT_EQ("2", 0, path().getSize());
}
void testConstruct2()
{
path p(comp("foo"));
VASSERT_EQ("1", false, p.isEmpty());
VASSERT_EQ("2", 1, p.getSize());
VASSERT_EQ("3", "foo", p.getComponentAt(0).getBuffer());
}
void testAppendComponent()
{
path p;
VASSERT_EQ("1", 0, p.getSize());
comp c("foo");
p.appendComponent(c);
VASSERT_EQ("2", 1, p.getSize());
VASSERT_EQ("3", c.getBuffer(), p.getComponentAt(0).getBuffer());
}
void testConstruct3()
{
path p1;
p1.appendComponent(comp("foo"));
p1.appendComponent(comp("bar"));
path p2(p1);
VASSERT_EQ("1", 2, p2.getSize());
VASSERT_EQ("2", "foo", p2.getComponentAt(0).getBuffer());
VASSERT_EQ("3", "bar", p2.getComponentAt(1).getBuffer());
}
void testConstruct4()
{
// Same as path::path(const component&)
path p("foo");
VASSERT_EQ("1", false, p.isEmpty());
VASSERT_EQ("2", 1, p.getSize());
VASSERT_EQ("3", "foo", p.getComponentAt(0).getBuffer());
}
void testOperatorDiv1()
{
path p1;
p1.appendComponent(comp("foo"));
p1.appendComponent(comp("bar"));
void testConstruct1() path p2;
{ p2.appendComponent(comp("baz"));
assert_eq("1", true, path().isEmpty());
assert_eq("2", 0, path().getSize());
}
void testConstruct2()
{
path p(comp("foo"));
assert_eq("1", false, p.isEmpty());
assert_eq("2", 1, p.getSize());
assert_eq("3", "foo", p.getComponentAt(0).getBuffer());
}
void testAppendComponent() path p3 = p1 / p2;
{
path p; VASSERT_EQ("1", 3, p3.getSize());
VASSERT_EQ("2", p1.getComponentAt(0).getBuffer(), p3.getComponentAt(0).getBuffer());
VASSERT_EQ("3", p1.getComponentAt(1).getBuffer(), p3.getComponentAt(1).getBuffer());
VASSERT_EQ("4", p2.getComponentAt(0).getBuffer(), p3.getComponentAt(2).getBuffer());
}
void testOperatorDiv2()
{
path p1;
p1.appendComponent(comp("foo"));
p1.appendComponent(comp("bar"));
comp c("baz");
path p2 = p1 / c;
VASSERT_EQ("1", 3, p2.getSize());
VASSERT_EQ("2", p1.getComponentAt(0).getBuffer(), p2.getComponentAt(0).getBuffer());
VASSERT_EQ("3", p1.getComponentAt(1).getBuffer(), p2.getComponentAt(1).getBuffer());
VASSERT_EQ("4", c.getBuffer(), p2.getComponentAt(2).getBuffer());
}
void testOperatorDivEqual1()
{
path p1;
p1.appendComponent(comp("foo"));
p1.appendComponent(comp("bar"));
path p2;
p2.appendComponent(comp("baz"));
path p3(p1);
p3 /= p2;
VASSERT_EQ("1", 3, p3.getSize());
VASSERT_EQ("2", p1.getComponentAt(0).getBuffer(), p3.getComponentAt(0).getBuffer());
VASSERT_EQ("3", p1.getComponentAt(1).getBuffer(), p3.getComponentAt(1).getBuffer());
VASSERT_EQ("4", p2.getComponentAt(0).getBuffer(), p3.getComponentAt(2).getBuffer());
}
void testOperatorDivEqual2()
{
path p1;
p1.appendComponent(comp("foo"));
p1.appendComponent(comp("bar"));
comp c("baz");
path p2(p1);
p2 /= c;
VASSERT_EQ("1", 3, p2.getSize());
VASSERT_EQ("2", p1.getComponentAt(0).getBuffer(), p2.getComponentAt(0).getBuffer());
VASSERT_EQ("3", p1.getComponentAt(1).getBuffer(), p2.getComponentAt(1).getBuffer());
VASSERT_EQ("4", c.getBuffer(), p2.getComponentAt(2).getBuffer());
}
void testGetParent()
{
path p1;
path p1p = p1.getParent();
VASSERT_EQ("1", true, p1p.isEmpty());
path p2;
p2.appendComponent(comp("foo"));
p2.appendComponent(comp("bar"));
path p2p = p2.getParent();
VASSERT_EQ("2", 1, p2p.getSize());
VASSERT_EQ("3", p2.getComponentAt(0).getBuffer(), p2p.getComponentAt(0).getBuffer());
}
void testComparison()
{
path p1;
p1.appendComponent(comp("foo"));
p1.appendComponent(comp("bar"));
path p2;
p2.appendComponent(comp("foo"));
p2.appendComponent(comp("bar"));
path p3;
p3.appendComponent(comp("foo"));
p3.appendComponent(comp("bar"));
p3.appendComponent(comp("baz"));
VASSERT_EQ("1", true, p1 == p2);
VASSERT_EQ("2", false, p1 == p3);
VASSERT_EQ("3", false, p1 != p2);
VASSERT_EQ("4", true, p1 != p3);
VASSERT_EQ("5", true, p3.getParent() == p1);
}
void testGetLastComponent()
{
path p1;
p1.appendComponent(comp("foo"));
p1.appendComponent(comp("bar"));
p1.appendComponent(comp("baz"));
VASSERT_EQ("1", "baz", p1.getLastComponent().getBuffer());
VASSERT_EQ("2", "bar", p1.getParent().getLastComponent().getBuffer());
VASSERT_EQ("3", "foo", p1.getParent().getParent().getLastComponent().getBuffer());
}
void testIsDirectParentOf()
{
path p1;
p1.appendComponent(comp("foo"));
path p2;
p2.appendComponent(comp("foo"));
p2.appendComponent(comp("bar"));
path p3;
p3.appendComponent(comp("foo"));
p3.appendComponent(comp("bar"));
p3.appendComponent(comp("baz"));
VASSERT_EQ("1", true, p1.isDirectParentOf(p2));
VASSERT_EQ("2", true, p2.isDirectParentOf(p3));
VASSERT_EQ("3", false, p1.isDirectParentOf(p3));
VASSERT_EQ("4", false, p2.isDirectParentOf(p1));
}
void testIsParentOf()
{
path p1;
p1.appendComponent(comp("foo"));
path p2;
p2.appendComponent(comp("foo"));
p2.appendComponent(comp("bar"));
path p3;
p3.appendComponent(comp("foo"));
p3.appendComponent(comp("bar"));
p3.appendComponent(comp("baz"));
VASSERT_EQ("1", true, p1.isParentOf(p2));
VASSERT_EQ("2", true, p2.isParentOf(p3));
VASSERT_EQ("3", true, p1.isParentOf(p3));
VASSERT_EQ("4", false, p2.isParentOf(p1));
}
void testRenameParent()
{
path p1;
p1.appendComponent(comp("a"));
p1.appendComponent(comp("b"));
p1.appendComponent(comp("c"));
p1.appendComponent(comp("d"));
path p2;
p2.appendComponent(comp("a"));
p2.appendComponent(comp("b"));
path p3;
p3.appendComponent(comp("x"));
p3.appendComponent(comp("y"));
p3.appendComponent(comp("z"));
path p(p1);
p.renameParent(p2, p3);
VASSERT_EQ("1", 5, p.getSize());
VASSERT_EQ("2", "x", p.getComponentAt(0).getBuffer());
VASSERT_EQ("3", "y", p.getComponentAt(1).getBuffer());
VASSERT_EQ("4", "z", p.getComponentAt(2).getBuffer());
VASSERT_EQ("5", "c", p.getComponentAt(3).getBuffer());
VASSERT_EQ("6", "d", p.getComponentAt(4).getBuffer());
}
VMIME_TEST_SUITE_END
assert_eq("1", 0, p.getSize());
comp c("foo");
p.appendComponent(c);
assert_eq("2", 1, p.getSize());
assert_eq("3", c.getBuffer(), p.getComponentAt(0).getBuffer());
}
void testConstruct3()
{
path p1;
p1.appendComponent(comp("foo"));
p1.appendComponent(comp("bar"));
path p2(p1);
assert_eq("1", 2, p2.getSize());
assert_eq("2", "foo", p2.getComponentAt(0).getBuffer());
assert_eq("3", "bar", p2.getComponentAt(1).getBuffer());
}
void testConstruct4()
{
// Same as path::path(const component&)
path p("foo");
assert_eq("1", false, p.isEmpty());
assert_eq("2", 1, p.getSize());
assert_eq("3", "foo", p.getComponentAt(0).getBuffer());
}
void testOperatorDiv1()
{
path p1;
p1.appendComponent(comp("foo"));
p1.appendComponent(comp("bar"));
path p2;
p2.appendComponent(comp("baz"));
path p3 = p1 / p2;
assert_eq("1", 3, p3.getSize());
assert_eq("2", p1.getComponentAt(0).getBuffer(), p3.getComponentAt(0).getBuffer());
assert_eq("3", p1.getComponentAt(1).getBuffer(), p3.getComponentAt(1).getBuffer());
assert_eq("4", p2.getComponentAt(0).getBuffer(), p3.getComponentAt(2).getBuffer());
}
void testOperatorDiv2()
{
path p1;
p1.appendComponent(comp("foo"));
p1.appendComponent(comp("bar"));
comp c("baz");
path p2 = p1 / c;
assert_eq("1", 3, p2.getSize());
assert_eq("2", p1.getComponentAt(0).getBuffer(), p2.getComponentAt(0).getBuffer());
assert_eq("3", p1.getComponentAt(1).getBuffer(), p2.getComponentAt(1).getBuffer());
assert_eq("4", c.getBuffer(), p2.getComponentAt(2).getBuffer());
}
void testOperatorDivEqual1()
{
path p1;
p1.appendComponent(comp("foo"));
p1.appendComponent(comp("bar"));
path p2;
p2.appendComponent(comp("baz"));
path p3(p1);
p3 /= p2;
assert_eq("1", 3, p3.getSize());
assert_eq("2", p1.getComponentAt(0).getBuffer(), p3.getComponentAt(0).getBuffer());
assert_eq("3", p1.getComponentAt(1).getBuffer(), p3.getComponentAt(1).getBuffer());
assert_eq("4", p2.getComponentAt(0).getBuffer(), p3.getComponentAt(2).getBuffer());
}
void testOperatorDivEqual2()
{
path p1;
p1.appendComponent(comp("foo"));
p1.appendComponent(comp("bar"));
comp c("baz");
path p2(p1);
p2 /= c;
assert_eq("1", 3, p2.getSize());
assert_eq("2", p1.getComponentAt(0).getBuffer(), p2.getComponentAt(0).getBuffer());
assert_eq("3", p1.getComponentAt(1).getBuffer(), p2.getComponentAt(1).getBuffer());
assert_eq("4", c.getBuffer(), p2.getComponentAt(2).getBuffer());
}
void testGetParent()
{
path p1;
path p1p = p1.getParent();
assert_eq("1", true, p1p.isEmpty());
path p2;
p2.appendComponent(comp("foo"));
p2.appendComponent(comp("bar"));
path p2p = p2.getParent();
assert_eq("2", 1, p2p.getSize());
assert_eq("3", p2.getComponentAt(0).getBuffer(), p2p.getComponentAt(0).getBuffer());
}
void testComparison()
{
path p1;
p1.appendComponent(comp("foo"));
p1.appendComponent(comp("bar"));
path p2;
p2.appendComponent(comp("foo"));
p2.appendComponent(comp("bar"));
path p3;
p3.appendComponent(comp("foo"));
p3.appendComponent(comp("bar"));
p3.appendComponent(comp("baz"));
assert_eq("1", true, p1 == p2);
assert_eq("2", false, p1 == p3);
assert_eq("3", false, p1 != p2);
assert_eq("4", true, p1 != p3);
assert_eq("5", true, p3.getParent() == p1);
}
void testGetLastComponent()
{
path p1;
p1.appendComponent(comp("foo"));
p1.appendComponent(comp("bar"));
p1.appendComponent(comp("baz"));
assert_eq("1", "baz", p1.getLastComponent().getBuffer());
assert_eq("2", "bar", p1.getParent().getLastComponent().getBuffer());
assert_eq("3", "foo", p1.getParent().getParent().getLastComponent().getBuffer());
}
void testIsDirectParentOf()
{
path p1;
p1.appendComponent(comp("foo"));
path p2;
p2.appendComponent(comp("foo"));
p2.appendComponent(comp("bar"));
path p3;
p3.appendComponent(comp("foo"));
p3.appendComponent(comp("bar"));
p3.appendComponent(comp("baz"));
assert_eq("1", true, p1.isDirectParentOf(p2));
assert_eq("2", true, p2.isDirectParentOf(p3));
assert_eq("3", false, p1.isDirectParentOf(p3));
assert_eq("4", false, p2.isDirectParentOf(p1));
}
void testIsParentOf()
{
path p1;
p1.appendComponent(comp("foo"));
path p2;
p2.appendComponent(comp("foo"));
p2.appendComponent(comp("bar"));
path p3;
p3.appendComponent(comp("foo"));
p3.appendComponent(comp("bar"));
p3.appendComponent(comp("baz"));
assert_eq("1", true, p1.isParentOf(p2));
assert_eq("2", true, p2.isParentOf(p3));
assert_eq("3", true, p1.isParentOf(p3));
assert_eq("4", false, p2.isParentOf(p1));
}
void testRenameParent()
{
path p1;
p1.appendComponent(comp("a"));
p1.appendComponent(comp("b"));
p1.appendComponent(comp("c"));
p1.appendComponent(comp("d"));
path p2;
p2.appendComponent(comp("a"));
p2.appendComponent(comp("b"));
path p3;
p3.appendComponent(comp("x"));
p3.appendComponent(comp("y"));
p3.appendComponent(comp("z"));
path p(p1);
p.renameParent(p2, p3);
assert_eq("1", 5, p.getSize());
assert_eq("2", "x", p.getComponentAt(0).getBuffer());
assert_eq("3", "y", p.getComponentAt(1).getBuffer());
assert_eq("4", "z", p.getComponentAt(2).getBuffer());
assert_eq("5", "c", p.getComponentAt(3).getBuffer());
assert_eq("6", "d", p.getComponentAt(4).getBuffer());
}
public:
pathTest() : suite("vmime::utility::path")
{
// VMime initialization
vmime::platformDependant::setHandler<vmime::platforms::posix::posixHandler>();
add("Construct1", testcase(this, "Construct1", &pathTest::testConstruct1));
add("Construct2", testcase(this, "Construct2", &pathTest::testConstruct2));
add("Construct3", testcase(this, "Construct3", &pathTest::testConstruct3));
add("Construct4", testcase(this, "Construct4", &pathTest::testConstruct4));
add("AppendComponent", testcase(this, "AppendComponent", &pathTest::testAppendComponent));
add("OperatorDiv1", testcase(this, "OperatorDiv1", &pathTest::testOperatorDiv1));
add("OperatorDiv2", testcase(this, "OperatorDiv2", &pathTest::testOperatorDiv2));
add("OperatorDivEqual1", testcase(this, "OperatorDivEqual1", &pathTest::testOperatorDivEqual1));
add("OperatorDivEqual2", testcase(this, "OperatorDivEqual2", &pathTest::testOperatorDivEqual2));
add("GetParent", testcase(this, "GetParent", &pathTest::testGetParent));
add("Comparison", testcase(this, "Comparison", &pathTest::testComparison));
add("GetLastComponent", testcase(this, "GetLastComponent", &pathTest::testGetLastComponent));
add("IsDirectParentOf", testcase(this, "IsDirectParentOf", &pathTest::testIsDirectParentOf));
add("IsParentOf", testcase(this, "IsParentOf", &pathTest::testIsParentOf));
add("RenameParent", testcase(this, "RenameParent", &pathTest::testRenameParent));
suite::main().add("vmime::utility::path", this);
}
};
pathTest* theTest = new pathTest();
}

View File

@ -17,242 +17,225 @@
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
// //
#include "../lib/unit++/unit++.h" #include "tests/testUtils.hpp"
#include <iostream>
#include <ostream>
#include <vector>
#include "vmime/vmime.hpp"
#include "vmime/platforms/posix/posixHandler.hpp"
#include "vmime/utility/smartPtr.hpp" #include "vmime/utility/smartPtr.hpp"
using namespace unitpp;
#define VMIME_TEST_SUITE smartPtrTest
#define VMIME_TEST_SUITE_MODULE "Utility"
namespace VMIME_TEST_SUITE_BEGIN
{
class smartPtrTest : public suite VMIME_TEST_LIST_BEGIN
VMIME_TEST(testNull)
VMIME_TEST(testRefCounting)
VMIME_TEST(testWeakRef)
VMIME_TEST(testCast)
VMIME_TEST(testContainer)
VMIME_TEST(testCompare)
VMIME_TEST_LIST_END
struct A : public vmime::object
{ {
struct A : public vmime::object const int strongCount() const { return getStrongRefCount(); }
{ const int weakCount() const { return getWeakRefCount(); }
const int strongCount() const { return getStrongRefCount(); }
const int weakCount() const { return getWeakRefCount(); }
};
struct B : public virtual A { };
struct C : public virtual A { };
struct D : public B, public C { };
class R : public A
{
public:
R(bool* aliveFlag) : m_aliveFlag(aliveFlag) { *m_aliveFlag = true; }
~R() { *m_aliveFlag = false; }
private:
bool* m_aliveFlag;
};
void testNull()
{
vmime::ref <A> r1;
assert_true("1", r1 == NULL);
assert_true("2", r1 == 0);
assert_true("3", NULL == r1);
assert_true("4", 0 == r1);
assert_true("5", !r1);
assert_true("6", r1 == vmime::null);
assert_true("7", vmime::null == r1);
assert_eq("8", static_cast <A*>(0), r1.get());
}
void testRefCounting()
{
bool o1_alive;
vmime::ref <R> r1 = vmime::create <R>(&o1_alive);
assert_true("1", r1.get() != 0);
assert_true("2", o1_alive);
assert_eq("3", 1, r1->strongCount());
assert_eq("4", 0, r1->weakCount());
vmime::ref <R> r2 = r1;
assert_true("5", o1_alive);
assert_eq("6", 2, r1->strongCount());
assert_eq("7", 0, r1->weakCount());
bool o2_alive;
vmime::ref <R> r3 = vmime::create <R>(&o2_alive);
r2 = r3;
assert_true("8", o1_alive);
assert_true("9", o2_alive);
assert_eq("10", 1, r1->strongCount());
assert_eq("11", 2, r2->strongCount());
assert_eq("12", 2, r3->strongCount());
{
vmime::ref <R> r4;
r4 = r1;
assert_true("13", o1_alive);
assert_true("14", o2_alive);
assert_eq("15", 2, r4->strongCount());
assert_eq("16", 2, r1->strongCount());
r1 = NULL;
assert_true("17", o1_alive);
assert_true("18", o2_alive);
assert_eq("19", 1, r4->strongCount());
// Here, object1 will be deleted
}
assert_true("20", !o1_alive);
assert_true("21", o2_alive);
{
vmime::weak_ref <R> w1 = r3;
assert_eq("22", 1, r3->weakCount());
}
assert_true("23", o2_alive);
assert_eq("24", 2, r3->strongCount());
assert_eq("25", 0, r3->weakCount());
}
void testWeakRef()
{
vmime::ref <A> r1 = vmime::create <A>();
vmime::weak_ref <A> w1 = r1;
assert_true("1", r1.get() != 0);
assert_true("2", r1.get() == w1.get());
{
vmime::ref <A> r2 = r1;
assert_true("3", r1.get() == r2.get());
assert_true("4", r1.get() == w1.get());
}
assert_true("5", r1.get() != 0);
assert_true("6", r1.get() == w1.get());
r1 = 0;
assert_true("7", w1.get() == 0);
}
void testCast()
{
// Explicit upcast
vmime::ref <A> r1 = vmime::create <C>();
vmime::ref <C> r2 = r1.dynamicCast <C>();
assert_true("1", r2.get() == dynamic_cast <C*>(r1.get()));
assert_true("2", 0 == r1.dynamicCast <B>().get());
// Implicit downcast
vmime::ref <D> r3 = vmime::create <D>();
vmime::ref <A> r4 = r3;
assert_true("3", r4.get() == dynamic_cast <A*>(r3.get()));
}
void testContainer()
{
bool o1_alive;
vmime::ref <R> r1 = vmime::create <R>(&o1_alive);
bool o2_alive;
vmime::ref <R> r2 = vmime::create <R>(&o2_alive);
std::vector <vmime::ref <R> > v1;
v1.push_back(r1);
v1.push_back(r2);
assert_true("1", o1_alive);
assert_eq("2", 2, r1->strongCount());
assert_true("3", o2_alive);
assert_eq("4", 2, r2->strongCount());
{
std::vector <vmime::ref <R> > v2 = v1;
assert_true("5", o1_alive);
assert_eq("6", 3, r1->strongCount());
assert_true("7", o2_alive);
assert_eq("8", 3, r2->strongCount());
v2[1] = NULL;
assert_true("9", o1_alive);
assert_eq("10", 3, r1->strongCount());
assert_true("11", o2_alive);
assert_eq("12", 2, r2->strongCount());
}
assert_true("13", o1_alive);
assert_eq("14", 2, r1->strongCount());
assert_true("15", o2_alive);
assert_eq("16", 2, r2->strongCount());
}
void testCompare()
{
vmime::ref <A> r1 = vmime::create <A>();
vmime::ref <A> r2 = vmime::create <B>();
vmime::ref <A> r3 = vmime::create <C>();
vmime::ref <A> r4 = r1;
assert_true("1", r1 != r2);
assert_true("2", r1.get() == r1);
assert_true("3", r1 == r1.get());
assert_true("4", r2 != r1.get());
assert_true("5", r1.get() != r2);
assert_true("6", r1 == r4);
assert_true("7", r1.get() == r4);
std::vector <vmime::ref <A> > v;
v.push_back(r1);
v.push_back(r2);
assert_true("8", std::find(v.begin(), v.end(), r1) == v.begin());
assert_true("9", std::find(v.begin(), v.end(), r2) == v.begin() + 1);
assert_true("10", std::find(v.begin(), v.end(), r3) == v.end());
}
public:
smartPtrTest() : suite("vmime::utility::url")
{
// VMime initialization
vmime::platformDependant::setHandler<vmime::platforms::posix::posixHandler>();
add("Null", testcase(this, "TestNull", &smartPtrTest::testNull));
add("RefCounting", testcase(this, "TestRefCounting", &smartPtrTest::testRefCounting));
add("WeakRef", testcase(this, "TestWeakRef", &smartPtrTest::testWeakRef));
add("Cast", testcase(this, "TestCast", &smartPtrTest::testCast));
add("Container", testcase(this, "TestContainer", &smartPtrTest::testContainer));
add("Compare", testcase(this, "TestCompare", &smartPtrTest::testCompare));
suite::main().add("vmime::utility::smartPtr", this);
}
}; };
smartPtrTest* theTest = new smartPtrTest(); struct B : public virtual A { };
} struct C : public virtual A { };
struct D : public B, public C { };
class R : public A
{
public:
R(bool* aliveFlag) : m_aliveFlag(aliveFlag) { *m_aliveFlag = true; }
~R() { *m_aliveFlag = false; }
private:
bool* m_aliveFlag;
};
void testNull()
{
vmime::ref <A> r1;
VASSERT("1", r1 == NULL);
VASSERT("2", r1 == 0);
VASSERT("3", NULL == r1);
VASSERT("4", 0 == r1);
VASSERT("5", !r1);
VASSERT("6", r1 == vmime::null);
VASSERT("7", vmime::null == r1);
VASSERT_EQ("8", static_cast <A*>(0), r1.get());
}
void testRefCounting()
{
bool o1_alive;
vmime::ref <R> r1 = vmime::create <R>(&o1_alive);
VASSERT("1", r1.get() != 0);
VASSERT("2", o1_alive);
VASSERT_EQ("3", 1, r1->strongCount());
VASSERT_EQ("4", 0, r1->weakCount());
vmime::ref <R> r2 = r1;
VASSERT("5", o1_alive);
VASSERT_EQ("6", 2, r1->strongCount());
VASSERT_EQ("7", 0, r1->weakCount());
bool o2_alive;
vmime::ref <R> r3 = vmime::create <R>(&o2_alive);
r2 = r3;
VASSERT("8", o1_alive);
VASSERT("9", o2_alive);
VASSERT_EQ("10", 1, r1->strongCount());
VASSERT_EQ("11", 2, r2->strongCount());
VASSERT_EQ("12", 2, r3->strongCount());
{
vmime::ref <R> r4;
r4 = r1;
VASSERT("13", o1_alive);
VASSERT("14", o2_alive);
VASSERT_EQ("15", 2, r4->strongCount());
VASSERT_EQ("16", 2, r1->strongCount());
r1 = NULL;
VASSERT("17", o1_alive);
VASSERT("18", o2_alive);
VASSERT_EQ("19", 1, r4->strongCount());
// Here, object1 will be deleted
}
VASSERT("20", !o1_alive);
VASSERT("21", o2_alive);
{
vmime::weak_ref <R> w1 = r3;
VASSERT_EQ("22", 1, r3->weakCount());
}
VASSERT("23", o2_alive);
VASSERT_EQ("24", 2, r3->strongCount());
VASSERT_EQ("25", 0, r3->weakCount());
}
void testWeakRef()
{
vmime::ref <A> r1 = vmime::create <A>();
vmime::weak_ref <A> w1 = r1;
VASSERT("1", r1.get() != 0);
VASSERT("2", r1.get() == w1.get());
{
vmime::ref <A> r2 = r1;
VASSERT("3", r1.get() == r2.get());
VASSERT("4", r1.get() == w1.get());
}
VASSERT("5", r1.get() != 0);
VASSERT("6", r1.get() == w1.get());
r1 = 0;
VASSERT("7", w1.get() == 0);
}
void testCast()
{
// Explicit upcast
vmime::ref <A> r1 = vmime::create <C>();
vmime::ref <C> r2 = r1.dynamicCast <C>();
VASSERT("1", r2.get() == dynamic_cast <C*>(r1.get()));
VASSERT("2", 0 == r1.dynamicCast <B>().get());
// Implicit downcast
vmime::ref <D> r3 = vmime::create <D>();
vmime::ref <A> r4 = r3;
VASSERT("3", r4.get() == dynamic_cast <A*>(r3.get()));
}
void testContainer()
{
bool o1_alive;
vmime::ref <R> r1 = vmime::create <R>(&o1_alive);
bool o2_alive;
vmime::ref <R> r2 = vmime::create <R>(&o2_alive);
std::vector <vmime::ref <R> > v1;
v1.push_back(r1);
v1.push_back(r2);
VASSERT("1", o1_alive);
VASSERT_EQ("2", 2, r1->strongCount());
VASSERT("3", o2_alive);
VASSERT_EQ("4", 2, r2->strongCount());
{
std::vector <vmime::ref <R> > v2 = v1;
VASSERT("5", o1_alive);
VASSERT_EQ("6", 3, r1->strongCount());
VASSERT("7", o2_alive);
VASSERT_EQ("8", 3, r2->strongCount());
v2[1] = NULL;
VASSERT("9", o1_alive);
VASSERT_EQ("10", 3, r1->strongCount());
VASSERT("11", o2_alive);
VASSERT_EQ("12", 2, r2->strongCount());
}
VASSERT("13", o1_alive);
VASSERT_EQ("14", 2, r1->strongCount());
VASSERT("15", o2_alive);
VASSERT_EQ("16", 2, r2->strongCount());
}
void testCompare()
{
vmime::ref <A> r1 = vmime::create <A>();
vmime::ref <A> r2 = vmime::create <B>();
vmime::ref <A> r3 = vmime::create <C>();
vmime::ref <A> r4 = r1;
VASSERT("1", r1 != r2);
VASSERT("2", r1.get() == r1);
VASSERT("3", r1 == r1.get());
VASSERT("4", r2 != r1.get());
VASSERT("5", r1.get() != r2);
VASSERT("6", r1 == r4);
VASSERT("7", r1.get() == r4);
std::vector <vmime::ref <A> > v;
v.push_back(r1);
v.push_back(r2);
VASSERT("8", std::find(v.begin(), v.end(), r1) == v.begin());
VASSERT("9", std::find(v.begin(), v.end(), r2) == v.begin() + 1);
VASSERT("10", std::find(v.begin(), v.end(), r3) == v.end());
}
VMIME_TEST_SUITE_END

View File

@ -17,189 +17,174 @@
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
// //
#include "../lib/unit++/unit++.h" #include "tests/testUtils.hpp"
#include <iostream>
#include <ostream>
#include "vmime/vmime.hpp"
#include "vmime/platforms/posix/posixHandler.hpp"
using namespace unitpp;
namespace #define VMIME_TEST_SUITE stringProxyTest
{ #define VMIME_TEST_SUITE_MODULE "Utility"
class stringProxyTest : public suite
VMIME_TEST_SUITE_BEGIN
VMIME_TEST_LIST_BEGIN
VMIME_TEST(testConstruct)
VMIME_TEST(testConstruct2)
VMIME_TEST(testDetach)
VMIME_TEST(testSet)
VMIME_TEST(testExtract)
VMIME_TEST(testOperatorLTLT1)
VMIME_TEST(testOperatorLTLT2)
VMIME_TEST_LIST_END
void testConstruct()
{ {
void testConstruct() vmime::utility::stringProxy s;
{
vmime::utility::stringProxy s;
assert_eq("1", static_cast <vmime::utility::stringProxy::size_type>(0), s.length()); VASSERT_EQ("1", static_cast <vmime::utility::stringProxy::size_type>(0), s.length());
assert_eq("2", static_cast <vmime::utility::stringProxy::size_type>(0), s.start()); VASSERT_EQ("2", static_cast <vmime::utility::stringProxy::size_type>(0), s.start());
assert_eq("3", static_cast <vmime::utility::stringProxy::size_type>(0), s.end()); VASSERT_EQ("3", static_cast <vmime::utility::stringProxy::size_type>(0), s.end());
} }
void testConstruct2() void testConstruct2()
{ {
vmime::string str("This is a test string."); vmime::string str("This is a test string.");
vmime::utility::stringProxy s1(str); vmime::utility::stringProxy s1(str);
assert_eq("1", str.length(), s1.length()); VASSERT_EQ("1", str.length(), s1.length());
assert_eq("2", static_cast <vmime::utility::stringProxy::size_type>(0), s1.start()); VASSERT_EQ("2", static_cast <vmime::utility::stringProxy::size_type>(0), s1.start());
assert_eq("3", str.length(), s1.end()); VASSERT_EQ("3", str.length(), s1.end());
vmime::utility::stringProxy s2(str, 10); vmime::utility::stringProxy s2(str, 10);
assert_eq("4", str.length() - 10, s2.length()); VASSERT_EQ("4", str.length() - 10, s2.length());
assert_eq("5", static_cast <vmime::utility::stringProxy::size_type>(10), s2.start()); VASSERT_EQ("5", static_cast <vmime::utility::stringProxy::size_type>(10), s2.start());
assert_eq("6", str.length(), s2.end()); VASSERT_EQ("6", str.length(), s2.end());
vmime::utility::stringProxy s3(str, 10, 14); vmime::utility::stringProxy s3(str, 10, 14);
assert_eq("7", static_cast <vmime::utility::stringProxy::size_type>(4), s3.length()); VASSERT_EQ("7", static_cast <vmime::utility::stringProxy::size_type>(4), s3.length());
assert_eq("8", static_cast <vmime::utility::stringProxy::size_type>(10), s3.start()); VASSERT_EQ("8", static_cast <vmime::utility::stringProxy::size_type>(10), s3.start());
assert_eq("9", static_cast <vmime::utility::stringProxy::size_type>(14), s3.end()); VASSERT_EQ("9", static_cast <vmime::utility::stringProxy::size_type>(14), s3.end());
assert_eq("10", 't', *s3.it_begin()); VASSERT_EQ("10", 't', *s3.it_begin());
assert_eq("11", 'e', *(s3.it_begin() + 1)); VASSERT_EQ("11", 'e', *(s3.it_begin() + 1));
assert_eq("12", 's', *(s3.it_begin() + 2)); VASSERT_EQ("12", 's', *(s3.it_begin() + 2));
assert_eq("13", 't', *(s3.it_begin() + 3)); VASSERT_EQ("13", 't', *(s3.it_begin() + 3));
} }
void testDetach() void testDetach()
{ {
vmime::utility::stringProxy s; vmime::utility::stringProxy s;
s = "foo"; s = "foo";
s.detach(); s.detach();
assert_eq("1", static_cast <vmime::utility::stringProxy::size_type>(0), s.length()); VASSERT_EQ("1", static_cast <vmime::utility::stringProxy::size_type>(0), s.length());
assert_eq("2", static_cast <vmime::utility::stringProxy::size_type>(0), s.start()); VASSERT_EQ("2", static_cast <vmime::utility::stringProxy::size_type>(0), s.start());
assert_eq("3", static_cast <vmime::utility::stringProxy::size_type>(0), s.end()); VASSERT_EQ("3", static_cast <vmime::utility::stringProxy::size_type>(0), s.end());
} }
void testSet() void testSet()
{ {
vmime::string str("This is a test string."); vmime::string str("This is a test string.");
vmime::utility::stringProxy s1; vmime::utility::stringProxy s1;
s1.set(str); s1.set(str);
assert_eq("1", str.length(), s1.length()); VASSERT_EQ("1", str.length(), s1.length());
assert_eq("2", static_cast <vmime::utility::stringProxy::size_type>(0), s1.start()); VASSERT_EQ("2", static_cast <vmime::utility::stringProxy::size_type>(0), s1.start());
assert_eq("3", str.length(), s1.end()); VASSERT_EQ("3", str.length(), s1.end());
vmime::utility::stringProxy s2; vmime::utility::stringProxy s2;
s2.set(str, 10); s2.set(str, 10);
assert_eq("4", str.length() - 10, s2.length()); VASSERT_EQ("4", str.length() - 10, s2.length());
assert_eq("5", static_cast <vmime::utility::stringProxy::size_type>(10), s2.start()); VASSERT_EQ("5", static_cast <vmime::utility::stringProxy::size_type>(10), s2.start());
assert_eq("6", str.length(), s2.end()); VASSERT_EQ("6", str.length(), s2.end());
vmime::utility::stringProxy s3; vmime::utility::stringProxy s3;
s3.set(str, 10, 14); s3.set(str, 10, 14);
assert_eq("7", static_cast <vmime::utility::stringProxy::size_type>(4), s3.length()); VASSERT_EQ("7", static_cast <vmime::utility::stringProxy::size_type>(4), s3.length());
assert_eq("8", static_cast <vmime::utility::stringProxy::size_type>(10), s3.start()); VASSERT_EQ("8", static_cast <vmime::utility::stringProxy::size_type>(10), s3.start());
assert_eq("9", static_cast <vmime::utility::stringProxy::size_type>(14), s3.end()); VASSERT_EQ("9", static_cast <vmime::utility::stringProxy::size_type>(14), s3.end());
assert_eq("10", 't', *s3.it_begin()); VASSERT_EQ("10", 't', *s3.it_begin());
assert_eq("11", 'e', *(s3.it_begin() + 1)); VASSERT_EQ("11", 'e', *(s3.it_begin() + 1));
assert_eq("12", 's', *(s3.it_begin() + 2)); VASSERT_EQ("12", 's', *(s3.it_begin() + 2));
assert_eq("13", 't', *(s3.it_begin() + 3)); VASSERT_EQ("13", 't', *(s3.it_begin() + 3));
} }
void testExtract() void testExtract()
{ {
vmime::string str("This is a test string."); vmime::string str("This is a test string.");
vmime::utility::stringProxy s1(str, 10, 14); vmime::utility::stringProxy s1(str, 10, 14);
std::ostringstream oss1; std::ostringstream oss1;
vmime::utility::outputStreamAdapter osa1(oss1); vmime::utility::outputStreamAdapter osa1(oss1);
s1.extract(osa1); s1.extract(osa1);
assert_eq("1", "test", oss1.str()); VASSERT_EQ("1", "test", oss1.str());
vmime::utility::stringProxy s2(str); vmime::utility::stringProxy s2(str);
std::ostringstream oss2; std::ostringstream oss2;
vmime::utility::outputStreamAdapter osa2(oss2); vmime::utility::outputStreamAdapter osa2(oss2);
s2.extract(osa2); s2.extract(osa2);
assert_eq("2", str, oss2.str()); VASSERT_EQ("2", str, oss2.str());
} }
void testOperatorLTLT1() void testOperatorLTLT1()
{ {
vmime::string str("This is a test string."); vmime::string str("This is a test string.");
vmime::utility::stringProxy s1(str, 10, 14); vmime::utility::stringProxy s1(str, 10, 14);
std::ostringstream oss1; std::ostringstream oss1;
oss1 << s1; oss1 << s1;
assert_eq("1", "test", oss1.str()); VASSERT_EQ("1", "test", oss1.str());
vmime::utility::stringProxy s2(str); vmime::utility::stringProxy s2(str);
std::ostringstream oss2; std::ostringstream oss2;
oss2 << s2; oss2 << s2;
assert_eq("2", str, oss2.str()); VASSERT_EQ("2", str, oss2.str());
} }
void testOperatorLTLT2() void testOperatorLTLT2()
{ {
vmime::string str("This is a test string."); vmime::string str("This is a test string.");
vmime::utility::stringProxy s1(str, 10, 14); vmime::utility::stringProxy s1(str, 10, 14);
std::ostringstream oss1; std::ostringstream oss1;
vmime::utility::outputStreamAdapter osa1(oss1); vmime::utility::outputStreamAdapter osa1(oss1);
osa1 << s1; osa1 << s1;
assert_eq("1", "test", oss1.str()); VASSERT_EQ("1", "test", oss1.str());
vmime::utility::stringProxy s2(str); vmime::utility::stringProxy s2(str);
std::ostringstream oss2; std::ostringstream oss2;
vmime::utility::outputStreamAdapter osa2(oss2); vmime::utility::outputStreamAdapter osa2(oss2);
osa2 << s2; osa2 << s2;
assert_eq("2", str, oss2.str()); VASSERT_EQ("2", str, oss2.str());
} }
public: VMIME_TEST_SUITE_END
stringProxyTest() : suite("vmime::utility::stringProxy")
{
// VMime initialization
vmime::platformDependant::setHandler<vmime::platforms::posix::posixHandler>();
add("Construct", testcase(this, "Construct", &stringProxyTest::testConstruct));
add("Construct2", testcase(this, "Construct2", &stringProxyTest::testConstruct2));
add("Detach", testcase(this, "Detach", &stringProxyTest::testDetach));
add("Set", testcase(this, "Set", &stringProxyTest::testSet));
add("Extract", testcase(this, "Extract", &stringProxyTest::testExtract));
add("Operator<<(1)", testcase(this, "Operator<<(1)", &stringProxyTest::testOperatorLTLT1));
add("Operator<<(2)", testcase(this, "Operator<<(2)", &stringProxyTest::testOperatorLTLT2));
suite::main().add("vmime::utility::stringProxy", this);
}
};
stringProxyTest* theTest = new stringProxyTest();
}

View File

@ -17,117 +17,103 @@
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
// //
#include "../lib/unit++/unit++.h" #include "tests/testUtils.hpp"
#include <iostream>
#include <ostream>
#include "vmime/vmime.hpp"
#include "vmime/platforms/posix/posixHandler.hpp"
#include "vmime/utility/stringUtils.hpp" #include "vmime/utility/stringUtils.hpp"
using namespace unitpp;
#define VMIME_TEST_SUITE stringUtilsTest
#define VMIME_TEST_SUITE_MODULE "Utility"
namespace VMIME_TEST_SUITE_BEGIN
{
class stringUtilsTest : public suite VMIME_TEST_LIST_BEGIN
VMIME_TEST(testIsStringEqualNoCase1)
VMIME_TEST(testIsStringEqualNoCase2)
VMIME_TEST(testIsStringEqualNoCase3)
VMIME_TEST(testToLower)
VMIME_TEST(testTrim)
VMIME_TEST(testCountASCIIChars)
VMIME_TEST_LIST_END
typedef vmime::utility::stringUtils stringUtils;
void testIsStringEqualNoCase1()
{ {
typedef vmime::utility::stringUtils stringUtils; VASSERT_EQ("1", true, stringUtils::isStringEqualNoCase(vmime::string("foo"), "foo", 3));
VASSERT_EQ("2", true, stringUtils::isStringEqualNoCase(vmime::string("FOo"), "foo", 3));
VASSERT_EQ("3", false, stringUtils::isStringEqualNoCase(vmime::string("foo"), "FOo", 3));
VASSERT_EQ("4", false, stringUtils::isStringEqualNoCase(vmime::string("foo"), "bar", 3));
}
void testIsStringEqualNoCase1() void testIsStringEqualNoCase2()
{ {
assert_eq("1", true, stringUtils::isStringEqualNoCase(vmime::string("foo"), "foo", 3)); VASSERT_EQ("1", true, stringUtils::isStringEqualNoCase(vmime::string("foo"), vmime::string("foo")));
assert_eq("2", true, stringUtils::isStringEqualNoCase(vmime::string("FOo"), "foo", 3)); VASSERT_EQ("2", true, stringUtils::isStringEqualNoCase(vmime::string("FOo"), vmime::string("foo")));
VASSERT_EQ("3", true, stringUtils::isStringEqualNoCase(vmime::string("foO"), vmime::string("FOo")));
}
assert_eq("3", false, stringUtils::isStringEqualNoCase(vmime::string("foo"), "FOo", 3)); void testIsStringEqualNoCase3()
assert_eq("4", false, stringUtils::isStringEqualNoCase(vmime::string("foo"), "bar", 3)); {
} vmime::string str1("FooBar");
void testIsStringEqualNoCase2() VASSERT_EQ("1", true, stringUtils::isStringEqualNoCase(str1.begin(), str1.end(), "foobar", 6));
{ VASSERT_EQ("2", false, stringUtils::isStringEqualNoCase(str1.begin(), str1.end(), "FooBar", 6));
assert_eq("1", true, stringUtils::isStringEqualNoCase(vmime::string("foo"), vmime::string("foo"))); VASSERT_EQ("3", true, stringUtils::isStringEqualNoCase(str1.begin(), str1.end(), "fooBar", 3));
assert_eq("2", true, stringUtils::isStringEqualNoCase(vmime::string("FOo"), vmime::string("foo"))); VASSERT_EQ("4", false, stringUtils::isStringEqualNoCase(str1.begin(), str1.begin() + 3, "fooBar", 6));
assert_eq("3", true, stringUtils::isStringEqualNoCase(vmime::string("foO"), vmime::string("FOo"))); }
}
void testIsStringEqualNoCase3() void testToLower()
{ {
vmime::string str1("FooBar"); VASSERT_EQ("1", "foo", stringUtils::toLower("FOO"));
VASSERT_EQ("2", "foo", stringUtils::toLower("foO"));
VASSERT_EQ("3", "foo", stringUtils::toLower("foo"));
}
assert_eq("1", true, stringUtils::isStringEqualNoCase(str1.begin(), str1.end(), "foobar", 6)); void testTrim()
assert_eq("2", false, stringUtils::isStringEqualNoCase(str1.begin(), str1.end(), "FooBar", 6)); {
assert_eq("3", true, stringUtils::isStringEqualNoCase(str1.begin(), str1.end(), "fooBar", 3)); VASSERT_EQ("1", "foo", stringUtils::trim(" foo"));
assert_eq("4", false, stringUtils::isStringEqualNoCase(str1.begin(), str1.begin() + 3, "fooBar", 6)); VASSERT_EQ("2", "foo", stringUtils::trim("\t\tfoo"));
} VASSERT_EQ("3", "foo", stringUtils::trim(" \t \tfoo"));
VASSERT_EQ("4", "foo", stringUtils::trim(" \r\n\tfoo"));
void testToLower() VASSERT_EQ("5", "foo", stringUtils::trim("foo "));
{ VASSERT_EQ("6", "foo", stringUtils::trim("foo\t\t"));
assert_eq("1", "foo", stringUtils::toLower("FOO")); VASSERT_EQ("7", "foo", stringUtils::trim("foo \t \t"));
assert_eq("2", "foo", stringUtils::toLower("foO")); VASSERT_EQ("8", "foo", stringUtils::trim("foo \r\n\t"));
assert_eq("3", "foo", stringUtils::toLower("foo"));
}
void testTrim() VASSERT_EQ( "9", "foo", stringUtils::trim("foo "));
{ VASSERT_EQ("10", "foo", stringUtils::trim(" foo "));
assert_eq("1", "foo", stringUtils::trim(" foo")); VASSERT_EQ("11", "foo", stringUtils::trim(" foo\t\t"));
assert_eq("2", "foo", stringUtils::trim("\t\tfoo")); VASSERT_EQ("12", "foo", stringUtils::trim("\tfoo \r \t"));
assert_eq("3", "foo", stringUtils::trim(" \t \tfoo")); VASSERT_EQ("13", "foo", stringUtils::trim("\r \tfoo \n\t"));
assert_eq("4", "foo", stringUtils::trim(" \r\n\tfoo")); }
assert_eq("5", "foo", stringUtils::trim("foo ")); void testCountASCIIChars()
assert_eq("6", "foo", stringUtils::trim("foo\t\t")); {
assert_eq("7", "foo", stringUtils::trim("foo \t \t")); vmime::string str1("foo");
assert_eq("8", "foo", stringUtils::trim("foo \r\n\t")); VASSERT_EQ("1", static_cast <vmime::string::size_type>(3),
stringUtils::countASCIIchars(str1.begin(), str1.end()));
assert_eq( "9", "foo", stringUtils::trim("foo ")); vmime::string str2("f=?oo");
assert_eq("10", "foo", stringUtils::trim(" foo ")); VASSERT_EQ("2", static_cast <vmime::string::size_type>(3 + 1),
assert_eq("11", "foo", stringUtils::trim(" foo\t\t")); stringUtils::countASCIIchars(str2.begin(), str2.end()));
assert_eq("12", "foo", stringUtils::trim("\tfoo \r \t"));
assert_eq("13", "foo", stringUtils::trim("\r \tfoo \n\t"));
}
void testCountASCIIChars() vmime::string str3("foo\x7f");
{ VASSERT_EQ("3", static_cast <vmime::string::size_type>(4),
vmime::string str1("foo"); stringUtils::countASCIIchars(str3.begin(), str3.end()));
assert_eq("1", static_cast <vmime::string::size_type>(3),
stringUtils::countASCIIchars(str1.begin(), str1.end()));
vmime::string str2("f=?oo"); vmime::string str4("foo\x80");
assert_eq("2", static_cast <vmime::string::size_type>(3 + 1), VASSERT_EQ("4", static_cast <vmime::string::size_type>(3),
stringUtils::countASCIIchars(str2.begin(), str2.end())); stringUtils::countASCIIchars(str4.begin(), str4.end()));
}
vmime::string str3("foo\x7f"); VMIME_TEST_SUITE_END
assert_eq("3", static_cast <vmime::string::size_type>(4),
stringUtils::countASCIIchars(str3.begin(), str3.end()));
vmime::string str4("foo\x80");
assert_eq("4", static_cast <vmime::string::size_type>(3),
stringUtils::countASCIIchars(str4.begin(), str4.end()));
}
public:
stringUtilsTest() : suite("vmime::utility::stringUtils")
{
// VMime initialization
vmime::platformDependant::setHandler<vmime::platforms::posix::posixHandler>();
add("IsStringEqualNoCase1", testcase(this, "IsStringEqualNoCase1", &stringUtilsTest::testIsStringEqualNoCase1));
add("IsStringEqualNoCase2", testcase(this, "IsStringEqualNoCase2", &stringUtilsTest::testIsStringEqualNoCase2));
add("IsStringEqualNoCase3", testcase(this, "IsStringEqualNoCase3", &stringUtilsTest::testIsStringEqualNoCase3));
add("ToLower", testcase(this, "ToLower", &stringUtilsTest::testToLower));
add("Trim", testcase(this, "Trim", &stringUtilsTest::testTrim));
add("CountASCIIChars", testcase(this, "CountASCIIChars", &stringUtilsTest::testCountASCIIChars));
suite::main().add("vmime::utility::stringUtils", this);
}
};
stringUtilsTest* theTest = new stringUtilsTest();
}

View File

@ -17,238 +17,223 @@
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
// //
#include "../lib/unit++/unit++.h" #include "tests/testUtils.hpp"
#include <iostream>
#include <ostream>
#include "vmime/vmime.hpp"
#include "vmime/platforms/posix/posixHandler.hpp"
#include "vmime/utility/url.hpp" #include "vmime/utility/url.hpp"
#include "vmime/utility/urlUtils.hpp" #include "vmime/utility/urlUtils.hpp"
using namespace unitpp;
#define VMIME_TEST_SUITE urlTest
#define VMIME_TEST_SUITE_MODULE "Utility"
namespace VMIME_TEST_SUITE_BEGIN
{
class urlTest : public suite VMIME_TEST_LIST_BEGIN
VMIME_TEST(testParse1)
VMIME_TEST(testParse2)
VMIME_TEST(testParse3)
VMIME_TEST(testParse4)
VMIME_TEST(testGenerate)
VMIME_TEST(testUtilsEncode)
VMIME_TEST(testUtilsDecode)
VMIME_TEST_LIST_END
static const bool parseHelper(vmime::utility::url& u, const vmime::string& str)
{ {
static const bool parseHelper(vmime::utility::url& u, const vmime::string& str) try
{ {
try u = vmime::utility::url(str);
{ }
u = vmime::utility::url(str); catch (vmime::exceptions::malformed_url)
} {
catch (vmime::exceptions::malformed_url) return false;
{
return false;
}
return true;
} }
return true;
}
void testParse1()
void testParse1()
{
// Test some valid constructions
vmime::utility::url u1("", "");
VASSERT_EQ("1.1", true, parseHelper(u1, "protocol://user:password@host:12345/path/"));
VASSERT_EQ("1.2", "protocol", u1.getProtocol());
VASSERT_EQ("1.3", "user", u1.getUsername());
VASSERT_EQ("1.4", "password", u1.getPassword());
VASSERT_EQ("1.5", "host", u1.getHost());
VASSERT_EQ("1.6", 12345, u1.getPort());
VASSERT_EQ("1.7", "/path/", u1.getPath());
vmime::utility::url u2("", "");
VASSERT_EQ("2.1", true, parseHelper(u2, "protocol://user@host:12345/path/"));
VASSERT_EQ("2.2", "protocol", u2.getProtocol());
VASSERT_EQ("2.3", "user", u2.getUsername());
VASSERT_EQ("2.4", "", u2.getPassword());
VASSERT_EQ("2.5", "host", u2.getHost());
VASSERT_EQ("2.6", 12345, u2.getPort());
VASSERT_EQ("2.7", "/path/", u2.getPath());
vmime::utility::url u3("", "");
VASSERT_EQ("3.1", true, parseHelper(u3, "protocol://host:12345/path/"));
VASSERT_EQ("3.2", "protocol", u3.getProtocol());
VASSERT_EQ("3.3", "", u3.getUsername());
VASSERT_EQ("3.4", "", u3.getPassword());
VASSERT_EQ("3.5", "host", u3.getHost());
VASSERT_EQ("3.6", 12345, u3.getPort());
VASSERT_EQ("3.7", "/path/", u3.getPath());
vmime::utility::url u4("", "");
VASSERT_EQ("4.1", true, parseHelper(u4, "protocol://host/path/"));
VASSERT_EQ("4.2", "protocol", u4.getProtocol());
VASSERT_EQ("4.3", "", u4.getUsername());
VASSERT_EQ("4.4", "", u4.getPassword());
VASSERT_EQ("4.5", "host", u4.getHost());
VASSERT_EQ("4.6", vmime::utility::url::UNSPECIFIED_PORT, u4.getPort());
VASSERT_EQ("4.7", "/path/", u4.getPath());
vmime::utility::url u5("", "");
VASSERT_EQ("5.1", true, parseHelper(u5, "protocol://host/"));
VASSERT_EQ("5.2", "protocol", u5.getProtocol());
VASSERT_EQ("5.3", "", u5.getUsername());
VASSERT_EQ("5.4", "", u5.getPassword());
VASSERT_EQ("5.5", "host", u5.getHost());
VASSERT_EQ("5.6", vmime::utility::url::UNSPECIFIED_PORT, u4.getPort());
VASSERT_EQ("5.7", "", u5.getPath());
vmime::utility::url u6("", "");
VASSERT_EQ("6.1", true, parseHelper(u4, "protocol://host/path/file"));
VASSERT_EQ("6.2", "protocol", u4.getProtocol());
VASSERT_EQ("6.3", "", u4.getUsername());
VASSERT_EQ("6.4", "", u4.getPassword());
VASSERT_EQ("6.5", "host", u4.getHost());
VASSERT_EQ("6.6", vmime::utility::url::UNSPECIFIED_PORT, u4.getPort());
VASSERT_EQ("6.7", "/path/file", u4.getPath());
}
void testParse2()
{
// Now, test some ill-formed URLs
// -- missing protocol
vmime::utility::url u1("", "");
VASSERT_EQ("1", false, parseHelper(u1, "://host"));
// -- port can contain only digits
vmime::utility::url u2("", "");
VASSERT_EQ("2", false, parseHelper(u2, "proto://host:abc123"));
// -- no host specified
vmime::utility::url u3("", "");
VASSERT_EQ("3", false, parseHelper(u3, "proto:///path"));
// -- no protocol separator (://)
vmime::utility::url u4("", "");
VASSERT_EQ("4", false, parseHelper(u4, "protohost/path"));
}
void testParse3()
{
// Test decoding
vmime::utility::url u1("", "");
VASSERT_EQ("1.1", true, parseHelper(u1, "pro%12to://user%34:pass%56word@ho%78st:12345/pa%abth/"));
VASSERT_EQ("1.2", "pro%12to", u1.getProtocol()); // protocol should not be decoded
VASSERT_EQ("1.3", "user\x34", u1.getUsername());
VASSERT_EQ("1.4", "pass\x56word", u1.getPassword());
VASSERT_EQ("1.5", "ho\x78st", u1.getHost());
VASSERT_EQ("1.6", 12345, u1.getPort());
VASSERT_EQ("1.7", "/pa\xabth/", u1.getPath());
}
void testParse4()
{
// Test parameters
vmime::utility::url u1("", "");
VASSERT_EQ("1.1", true, parseHelper(u1, "proto://host/path?p1=v1&p2=v2"));
VASSERT_EQ("1.2", "v1", u1.getParams().getProperty <vmime::string>("p1"));
VASSERT_EQ("1.3", "v2", u1.getParams().getProperty <vmime::string>("p2"));
VASSERT_EQ("1.4", "/path", u1.getPath());
vmime::utility::url u2("", "");
VASSERT_EQ("2.1", true, parseHelper(u2, "proto://host/path?p1=v1&p2"));
VASSERT_EQ("2.2", "v1", u2.getParams().getProperty <vmime::string>("p1"));
VASSERT_EQ("2.3", "p2", u2.getParams().getProperty <vmime::string>("p2"));
VASSERT_EQ("2.4", "/path", u2.getPath());
vmime::utility::url u3("", "");
VASSERT_EQ("3.1", true, parseHelper(u3, "proto://host/?p1=v1&p2=v2"));
VASSERT_EQ("3.2", "v1", u3.getParams().getProperty <vmime::string>("p1"));
VASSERT_EQ("3.3", "v2", u3.getParams().getProperty <vmime::string>("p2"));
VASSERT_EQ("3.4", "", u3.getPath());
vmime::utility::url u4("", "");
VASSERT_EQ("4.1", true, parseHelper(u4, "proto://host/path?p1=%3D&%3D=v2"));
VASSERT_EQ("4.2", "=", u4.getParams().getProperty <vmime::string>("p1"));
VASSERT_EQ("4.3", "v2", u4.getParams().getProperty <vmime::string>("="));
VASSERT_EQ("4.4", "/path", u4.getPath());
}
void testGenerate()
{
vmime::utility::url u1("proto", "host", 12345, "path", "user", "password");
VASSERT_EQ("1", "proto://user:password@host:12345/path",
static_cast <vmime::string>(u1));
vmime::utility::url u2("proto", "host");
VASSERT_EQ("2", "proto://host", static_cast <vmime::string>(u2));
vmime::utility::url u3("proto", "host");
u3.getParams().setProperty("p1", "v1");
VASSERT_EQ("3.1", "proto://host/?p1=v1",
static_cast <vmime::string>(u3));
u3.getParams().setProperty("p2", "v2");
VASSERT_EQ("3.2", "proto://host/?p1=v1&p2=v2",
static_cast <vmime::string>(u3));
u3.getParams().setProperty("&", "=");
VASSERT_EQ("3.3", "proto://host/?p1=v1&p2=v2&%26=%3D",
static_cast <vmime::string>(u3));
}
void testUtilsEncode()
{
VASSERT_EQ("1", "%01", vmime::utility::urlUtils::encode("\x01"));
VASSERT_EQ("2", "%20", vmime::utility::urlUtils::encode(" "));
VASSERT_EQ("3", "%FF", vmime::utility::urlUtils::encode("\xff"));
VASSERT_EQ("4", "a", vmime::utility::urlUtils::encode("a"));
}
void testUtilsDecode()
{
for (int i = 0 ; i < 255 ; ++i)
{ {
// Test some valid constructions std::ostringstream ossTest;
vmime::utility::url u1("", ""); ossTest << "%" << "0123456789ABCDEF"[i / 16]
<< "0123456789ABCDEF"[i % 16];
assert_eq("1.1", true, parseHelper(u1, "protocol://user:password@host:12345/path/")); std::ostringstream ossNum;
assert_eq("1.2", "protocol", u1.getProtocol()); ossNum << i;
assert_eq("1.3", "user", u1.getUsername());
assert_eq("1.4", "password", u1.getPassword());
assert_eq("1.5", "host", u1.getHost());
assert_eq("1.6", 12345, u1.getPort());
assert_eq("1.7", "/path/", u1.getPath());
vmime::utility::url u2("", ""); vmime::string res;
res += static_cast <unsigned char>(i);
assert_eq("2.1", true, parseHelper(u2, "protocol://user@host:12345/path/")); VASSERT_EQ(ossNum.str(), res,
assert_eq("2.2", "protocol", u2.getProtocol()); vmime::utility::urlUtils::decode(ossTest.str()));
assert_eq("2.3", "user", u2.getUsername());
assert_eq("2.4", "", u2.getPassword());
assert_eq("2.5", "host", u2.getHost());
assert_eq("2.6", 12345, u2.getPort());
assert_eq("2.7", "/path/", u2.getPath());
vmime::utility::url u3("", "");
assert_eq("3.1", true, parseHelper(u3, "protocol://host:12345/path/"));
assert_eq("3.2", "protocol", u3.getProtocol());
assert_eq("3.3", "", u3.getUsername());
assert_eq("3.4", "", u3.getPassword());
assert_eq("3.5", "host", u3.getHost());
assert_eq("3.6", 12345, u3.getPort());
assert_eq("3.7", "/path/", u3.getPath());
vmime::utility::url u4("", "");
assert_eq("4.1", true, parseHelper(u4, "protocol://host/path/"));
assert_eq("4.2", "protocol", u4.getProtocol());
assert_eq("4.3", "", u4.getUsername());
assert_eq("4.4", "", u4.getPassword());
assert_eq("4.5", "host", u4.getHost());
assert_eq("4.6", vmime::utility::url::UNSPECIFIED_PORT, u4.getPort());
assert_eq("4.7", "/path/", u4.getPath());
vmime::utility::url u5("", "");
assert_eq("5.1", true, parseHelper(u5, "protocol://host/"));
assert_eq("5.2", "protocol", u5.getProtocol());
assert_eq("5.3", "", u5.getUsername());
assert_eq("5.4", "", u5.getPassword());
assert_eq("5.5", "host", u5.getHost());
assert_eq("5.6", vmime::utility::url::UNSPECIFIED_PORT, u4.getPort());
assert_eq("5.7", "", u5.getPath());
vmime::utility::url u6("", "");
assert_eq("6.1", true, parseHelper(u4, "protocol://host/path/file"));
assert_eq("6.2", "protocol", u4.getProtocol());
assert_eq("6.3", "", u4.getUsername());
assert_eq("6.4", "", u4.getPassword());
assert_eq("6.5", "host", u4.getHost());
assert_eq("6.6", vmime::utility::url::UNSPECIFIED_PORT, u4.getPort());
assert_eq("6.7", "/path/file", u4.getPath());
} }
void testParse2() }
{
// Now, test some ill-formed URLs
// -- missing protocol VMIME_TEST_SUITE_END
vmime::utility::url u1("", "");
assert_eq("1", false, parseHelper(u1, "://host"));
// -- port can contain only digits
vmime::utility::url u2("", "");
assert_eq("2", false, parseHelper(u2, "proto://host:abc123"));
// -- no host specified
vmime::utility::url u3("", "");
assert_eq("3", false, parseHelper(u3, "proto:///path"));
// -- no protocol separator (://)
vmime::utility::url u4("", "");
assert_eq("4", false, parseHelper(u4, "protohost/path"));
}
void testParse3()
{
// Test decoding
vmime::utility::url u1("", "");
assert_eq("1.1", true, parseHelper(u1, "pro%12to://user%34:pass%56word@ho%78st:12345/pa%abth/"));
assert_eq("1.2", "pro%12to", u1.getProtocol()); // protocol should not be decoded
assert_eq("1.3", "user\x34", u1.getUsername());
assert_eq("1.4", "pass\x56word", u1.getPassword());
assert_eq("1.5", "ho\x78st", u1.getHost());
assert_eq("1.6", 12345, u1.getPort());
assert_eq("1.7", "/pa\xabth/", u1.getPath());
}
void testParse4()
{
// Test parameters
vmime::utility::url u1("", "");
assert_eq("1.1", true, parseHelper(u1, "proto://host/path?p1=v1&p2=v2"));
assert_eq("1.2", "v1", u1.getParams().getProperty <vmime::string>("p1"));
assert_eq("1.3", "v2", u1.getParams().getProperty <vmime::string>("p2"));
assert_eq("1.4", "/path", u1.getPath());
vmime::utility::url u2("", "");
assert_eq("2.1", true, parseHelper(u2, "proto://host/path?p1=v1&p2"));
assert_eq("2.2", "v1", u2.getParams().getProperty <vmime::string>("p1"));
assert_eq("2.3", "p2", u2.getParams().getProperty <vmime::string>("p2"));
assert_eq("2.4", "/path", u2.getPath());
vmime::utility::url u3("", "");
assert_eq("3.1", true, parseHelper(u3, "proto://host/?p1=v1&p2=v2"));
assert_eq("3.2", "v1", u3.getParams().getProperty <vmime::string>("p1"));
assert_eq("3.3", "v2", u3.getParams().getProperty <vmime::string>("p2"));
assert_eq("3.4", "", u3.getPath());
vmime::utility::url u4("", "");
assert_eq("4.1", true, parseHelper(u4, "proto://host/path?p1=%3D&%3D=v2"));
assert_eq("4.2", "=", u4.getParams().getProperty <vmime::string>("p1"));
assert_eq("4.3", "v2", u4.getParams().getProperty <vmime::string>("="));
assert_eq("4.4", "/path", u4.getPath());
}
void testGenerate()
{
vmime::utility::url u1("proto", "host", 12345, "path", "user", "password");
assert_eq("1", "proto://user:password@host:12345/path",
static_cast <vmime::string>(u1));
vmime::utility::url u2("proto", "host");
assert_eq("2", "proto://host", static_cast <vmime::string>(u2));
vmime::utility::url u3("proto", "host");
u3.getParams().setProperty("p1", "v1");
assert_eq("3.1", "proto://host/?p1=v1",
static_cast <vmime::string>(u3));
u3.getParams().setProperty("p2", "v2");
assert_eq("3.2", "proto://host/?p1=v1&p2=v2",
static_cast <vmime::string>(u3));
u3.getParams().setProperty("&", "=");
assert_eq("3.3", "proto://host/?p1=v1&p2=v2&%26=%3D",
static_cast <vmime::string>(u3));
}
void testUtilsEncode()
{
assert_eq("1", "%01", vmime::utility::urlUtils::encode("\x01"));
assert_eq("2", "%20", vmime::utility::urlUtils::encode(" "));
assert_eq("3", "%FF", vmime::utility::urlUtils::encode("\xff"));
assert_eq("4", "a", vmime::utility::urlUtils::encode("a"));
}
void testUtilsDecode()
{
for (int i = 0 ; i < 255 ; ++i)
{
std::ostringstream ossTest;
ossTest << "%" << "0123456789ABCDEF"[i / 16]
<< "0123456789ABCDEF"[i % 16];
std::ostringstream ossNum;
ossNum << i;
vmime::string res;
res += static_cast <unsigned char>(i);
assert_eq(ossNum.str(), res,
vmime::utility::urlUtils::decode(ossTest.str()));
}
}
public:
urlTest() : suite("vmime::utility::url")
{
// VMime initialization
vmime::platformDependant::setHandler<vmime::platforms::posix::posixHandler>();
add("Parse1", testcase(this, "Parse1", &urlTest::testParse1));
add("Parse2", testcase(this, "Parse2", &urlTest::testParse2));
add("Parse3", testcase(this, "Parse3", &urlTest::testParse3));
add("Parse4", testcase(this, "Parse4", &urlTest::testParse4));
add("Generate", testcase(this, "Generate", &urlTest::testGenerate));
add("UtilsEncode", testcase(this, "UtilsEncode", &urlTest::testUtilsEncode));
add("UtilsDecode", testcase(this, "UtilsDecode", &urlTest::testUtilsDecode));
suite::main().add("vmime::utility::url", this);
}
};
urlTest* theTest = new urlTest();
}