00001 #include <iostream>
00002
00003 #include "NewsgroupFilter.h"
00004
00005 #define V(x) if(verbose) { x; }
00006
00007 NewsgroupFilter filters[] = {
00008 NewsgroupFilter("at.*"),
00009 NewsgroupFilter("comp.*"),
00010 NewsgroupFilter("comp.*,!comp.os.windows.*"),
00011 NewsgroupFilter("at.*,!at.secret.*,!at.top.secret.*"),
00012 NewsgroupFilter("at.*,!at.top.secret.*,comp.os.linux.*"),
00013 NewsgroupFilter("at.*,!at.top.*"),
00014 NewsgroupFilter("at.*,!at.top.top.top.*"),
00015 NewsgroupFilter("at.top.top.*,!at.top.top.top.*")
00016 };
00017 int filters_n = sizeof(filters) / sizeof(filters[0]);
00018
00019 const char *newsgroups[] = {
00020 "at.tuwien.general",
00021 "comp.os.linux",
00022 "at.top.secret.aaa",
00023 "at.top.top.secret.xxx",
00024 "at.top.top.top.secret.yyy",
00025 "at.top.top.top.top.secret.zzz",
00026 "at.secret.bbb",
00027 "foo.bar"
00028 };
00029 int newsgroups_n = sizeof(newsgroups) / sizeof(newsgroups[0]);
00030
00031 int ef = 0;
00032 int verbose = 0;
00033
00034 #define MAX(X,Y) (((X)>(Y))?(X):(Y))
00035 #define MIN(X,Y) (((X)<(Y))?(X):(Y))
00036
00037 class CheckAND {
00038 public:
00039 void operator() (const NewsgroupFilter & f1,
00040 const NewsgroupFilter & f2) {
00041 NewsgroupFilter f1OPf2(f1);
00042 f1OPf2 &= f2;
00043
00044 for (int i = 0; i < newsgroups_n; i++) {
00045 int f1OPf2m =
00046 (f1OPf2.matches(newsgroups[i]) > 0) ? 1 : -1;
00047 int f1OPf2n = (f1.matches(newsgroups[i]) > 0
00048 && f2.matches(newsgroups[i]) >
00049 0) ? 1 : -1;
00050
00051 if (f1OPf2n == f1OPf2m) {
00052 cout << "+" << flush;
00053 } else {
00054 cout << "-" << flush;
00055 ef++;
00056 V(cout << endl;
00057 cout << "{" << f1 << "} and {" << f2 <<
00058 "}=={" << f1OPf2 << "}" << endl;
00059 cout << newsgroups[i] << flush;
00060 );
00061 }
00062 }
00063 cout << " " << flush;
00064 }
00065 };
00066
00067 class CheckOR {
00068 public:
00069 void operator() (const NewsgroupFilter & f1,
00070 const NewsgroupFilter & f2) {
00071 NewsgroupFilter f1OPf2(f1);
00072 f1OPf2 |= f2;
00073
00074 for (int i = 0; i < newsgroups_n; i++) {
00075 int f1OPf2m =
00076 (f1OPf2.matches(newsgroups[i]) > 0) ? 1 : -1;
00077 int f1OPf2n = (f1.matches(newsgroups[i]) > 0
00078 || f2.matches(newsgroups[i]) >
00079 0) ? 1 : -1;
00080
00081 if (f1OPf2n == f1OPf2m) {
00082 cout << "+" << flush;
00083 } else {
00084 cout << "-" << flush;
00085 ef++;
00086 V(cout << endl;
00087 cout << "{" << f1 << "} and {" << f2 <<
00088 "}=={" << f1OPf2 << "}" << endl;
00089 cout << newsgroups[i] << flush;
00090 );
00091 }
00092 }
00093 cout << " " << flush;
00094 }
00095 };
00096
00097 template < class Check > void combine_filters(Check check)
00098 {
00099 for (int i = 0; i < filters_n; i++) {
00100 NewsgroupFilter fi(filters[i]);
00101 cout << i << ": " << flush;
00102 for (int j = 0; j < filters_n; j++) {
00103 NewsgroupFilter fj(filters[j]);
00104 check(fi, fj);
00105 }
00106 cout << endl;
00107 }
00108 }
00109
00110 int main(int argc, char *argv[])
00111 {
00112 if (argc > 1 && strcmp(argv[1], "-v") == 0)
00113 verbose = 1;
00114 cout << "cNewsgroupFilter:\n";
00115
00116 cout << "operator&=:\n";
00117 combine_filters(CheckAND());
00118
00119 cout << "operator|=:\n";
00120 combine_filters(CheckOR());
00121
00122 if (ef == 0) {
00123 cout << "cNewsgroupFilter: all tests succeeded\n";
00124 exit(0);
00125 } else {
00126 cout << "cNewsgroupFilter: " << ef << " failures\n";
00127 exit(-1);
00128 }
00129 }