MySQL 5.6.14 Source Code Document
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Properties_test.cpp
1 /*
2  Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved.
3 
4  This program is free software; you can redistribute it and/or modify
5  it under the terms of the GNU General Public License as published by
6  the Free Software Foundation; version 2 of the License.
7 
8  This program is distributed in the hope that it will be useful,
9  but WITHOUT ANY WARRANTY; without even the implied warranty of
10  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11  GNU General Public License for more details.
12 
13  You should have received a copy of the GNU General Public License
14  along with this program; if not, write to the Free Software
15  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
16 */
17 
18 /*
19  * Properties.cpp
20  *
21  */
22 
23 #include <sstream>
24 #include <cassert>
25 #include <cstdlib>
26 
27 #include "Properties.hpp"
28 
29 using std::cout;
30 using std::wcout;
31 using std::endl;
32 using std::string;
33 using std::wstring;
34 using std::stringbuf;
35 
36 using utils::Properties;
37 
38 //template <class C, size_t N> size_t dim_array (C (&) [N]) { return N; }
39 // usage: int n = dim_array(array); // == sizeof(array)/sizeof(*array)
40 
41 void test()
42 {
43  cout << "--> test()" << endl;
44 
45  // test objects
46  Properties p;
47  const wstring k(L"key");
48  const wstring v(L"value");
49  const wstring w(L"");
50 
51  // test comments, empty lines
52  const char* kv0[] = {
53  "", "\n", "\r", "\n\n", "\n\r", "\r\n", "\r\r", "\r\n\r", "\n\r\n",
54  "#", "#k", "#\n", "#\\", "#\\\\", "#\\\n", "#\\\n\n",
55  "!", "!k", "!\n", "!\\", "!\\\\", "!\\\n", "!\\\n\n",
56  " #k", "\f#k", "\t#k",
57  " #k", "\f #k", "\t #k",
58  "#kkk", "#kkk vvv", "#kkk= vvv", "#kkk: vvv",
59  "# kkk", "# kkk vvv", "# kkk= vvv", "# kkk: vvv",
60  };
61  const int n0 = sizeof(kv0)/sizeof(*kv0);
62  for (int i = 0; i < n0; ++i ) {
63  //cout << "[" << i << "] " << "'" << kv0[i] << "'" << endl;
64  stringbuf sb(kv0[i]);
65  p.load(sb);
66  assert (p.size() == 0);
67  }
68 
69  // test non-empty key, value pairs
70  const char* kv1[] = {
71  "key=value", "key=value\n", "key=value\r", "key=value\r\n",
72  "key:value", "key=value\n", "key=value\r", "key=value\r\n",
73  "key value", "key\fvalue", "key\tvalue", "key value\n",
74  " key=value", "\fkey=value", "\tkey=value",
75  "key =value", "key\f=value", "key\t=value",
76  " key =value", "\fkey\f=value", "\tkey\t=value",
77  "key= value", "key=\fvalue", "key=\tvalue",
78  "key= value", "key value", "key value", "key \t \fvalue",
79  };
80  const int n1 = sizeof(kv1)/sizeof(*kv1);
81  for (int i = 0; i < n1; ++i ) {
82  //cout << "[" << i << "] " << "'" << kv1[i] << "'" << endl;
83  stringbuf sb(kv1[i]);
84  p.load(sb);
85  assert (p.size() == 1);
86  Properties::const_iterator e = p.begin();
87  //wcout << e->first << " => " << e->second << endl;
88  assert (e->first == k);
89  assert (e->second == v);
90  p.clear();
91  }
92 
93  // test single keys (empty values)
94  const char* kv2[] = {
95  "key", "key ", " key ", "key\n", " \fkey \t\n",
96  "key=", "key =", "key= ", "key = ", "key=\n", " \fkey \t= \f\r\n",
97  };
98  const int n2 = sizeof(kv2)/sizeof(*kv2);
99  for (int i = 0; i < n2; ++i ) {
100  //cout << "[" << i << "] " << "'" << kv2[i] << "'" << endl;
101  stringbuf sb(kv2[i]);
102  p.load(sb);
103  assert (p.size() == 1);
104  Properties::const_iterator e = p.begin();
105  //wcout << e->first << " => " << e->second << endl;
106  assert (e->first == k);
107  assert (e->second == w);
108  p.clear();
109  }
110 
111  // test escape sequences
112  const char* kv3[] = {
113  "key=value", "key=value\\\n", "key=value\\\r", "key=value\\\r\n",
114  "k\\\ney=va\\\nlue", "k\\\rey=va\\\rlue", "k\\\r\ney=va\\\r\nlue",
115  "k\\\n ey=va\\\n lue", "k\\\r ey=va\\\r lue", "k\\\r\n ey=va\\\r\n lue",
116  "k\\\n\\\ney=va\\\n\\\nlue", "k\\\r\\\ney=va\\\r\\\nlue",
117  "k\\\n \\\n ey=va\\\n \\\n lue", "k\\\r \\\n ey=va\\\r \\\n lue",
118  "k\\ey=va\\lue",
119  "\\u006b\\u0065\\u0079=\\u0076\\u0061\\u006C\\u0075\\u0065",
120  };
121  const int n3 = sizeof(kv3)/sizeof(*kv3);
122  for (int i = 0; i < n3; ++i ) {
123  //cout << "[" << i << "] " << "'" << kv3[i] << "'" << endl;
124  stringbuf sb(kv3[i]);
125  p.load(sb);
126  assert (p.size() == 1);
127  Properties::const_iterator e = p.begin();
128  //wcout << e->first << " => " << e->second << endl;
129  assert (e->first == k);
130  assert (e->second == v);
131  p.clear();
132  }
133 
134  // test store
135  const char* kv4 = ("\\ a\\ key\\ =\\ a value \n"
136  "key\\!=value\\!\n"
137  "key\\#=value\\#\n"
138  "key0=value0\n" "key1=value1\n"
139  "key2=\n" "key3=\n"
140  "key\\:=value\\:\n"
141  "key\\==value\\=\n");
142  {
143  //cout << "kv4='" << endl << kv4 << "'" << endl;
144  stringbuf ib(kv4);
145  p.load(ib);
146  //cout << "p={" << endl << p << "}" << endl;
147 
148  stringbuf ob;
149  p.store(ob);
150  //cout << "ib='" << ib.str() << "'" << endl;
151  //cout << "ob='" << ob.str() << "'" << endl;
152  assert (ib.str() == ob.str());
153 
154  Properties q;
155  q.load(ob);
156  //cout << "q={" << endl << q << "}" << endl;
157  assert (p == q);
158 
159  p.clear();
160  }
161 
162  cout << "all tests passed." << endl;
163  cout << "<-- test()" << endl;
164 }
165 
166 void
167 exitUsage()
168 {
169  cout << "usage: [options]" << endl
170  << " -p <file name> properties file name" << endl
171  << " -h|--help print usage message and exit" << endl
172  << endl;
173  exit(EXIT_FAILURE);
174 }
175 
176 int
177 main(int argc, const char* argv[])
178 {
179  cout << "--> main()" << endl;
180 
181  test();
182 
183  // parse and print a property file
184  if (argc > 1) {
185  const char* fn = NULL;
186  const string arg = argv[1];
187  if (arg.compare("-p") == 0) {
188  if (argc < 3) {
189  exitUsage();
190  }
191  fn = argv[2];
192  } else if (arg.compare("-h") == 0 || arg.compare("--help") == 0) {
193  exitUsage();
194  } else {
195  cout << "unknown option: " << arg << endl;
196  exitUsage();
197  }
198 
199  if (fn != NULL) {
200  Properties p;
201  cout << "read: " << fn << endl;
202  p.load(fn);
203 
204  cout << "print:" << endl;
205  wstring h(L"this header string passed to store() should be first");
206  p.store(cout, &h);
207  }
208  }
209 
210  cout << "<-- main()" << endl;
211  return 0;
212 }