|
1 /**************************************************************************** |
|
2 ** |
|
3 ** Copyright (C) 2009 Nokia Corporation and/or its subsidiary(-ies). |
|
4 ** All rights reserved. |
|
5 ** Contact: Nokia Corporation (qt-info@nokia.com) |
|
6 ** |
|
7 ** This file is part of the test suite of the Qt Toolkit. |
|
8 ** |
|
9 ** $QT_BEGIN_LICENSE:LGPL$ |
|
10 ** No Commercial Usage |
|
11 ** This file contains pre-release code and may not be distributed. |
|
12 ** You may use this file in accordance with the terms and conditions |
|
13 ** contained in the Technology Preview License Agreement accompanying |
|
14 ** this package. |
|
15 ** |
|
16 ** GNU Lesser General Public License Usage |
|
17 ** Alternatively, this file may be used under the terms of the GNU Lesser |
|
18 ** General Public License version 2.1 as published by the Free Software |
|
19 ** Foundation and appearing in the file LICENSE.LGPL included in the |
|
20 ** packaging of this file. Please review the following information to |
|
21 ** ensure the GNU Lesser General Public License version 2.1 requirements |
|
22 ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. |
|
23 ** |
|
24 ** In addition, as a special exception, Nokia gives you certain additional |
|
25 ** rights. These rights are described in the Nokia Qt LGPL Exception |
|
26 ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. |
|
27 ** |
|
28 ** If you have questions regarding the use of this file, please contact |
|
29 ** Nokia at qt-info@nokia.com. |
|
30 ** |
|
31 ** |
|
32 ** |
|
33 ** |
|
34 ** |
|
35 ** |
|
36 ** |
|
37 ** |
|
38 ** $QT_END_LICENSE$ |
|
39 ** |
|
40 ****************************************************************************/ |
|
41 |
|
42 |
|
43 #include <QtTest/QtTest> |
|
44 #include <QtGlobal> |
|
45 #include <QtAlgorithms> |
|
46 #include <QtNetwork/QHostInfo> |
|
47 |
|
48 #ifndef QT_NO_PRINTER |
|
49 #include <qprinterinfo.h> |
|
50 |
|
51 #ifdef Q_OS_UNIX |
|
52 # include <unistd.h> |
|
53 # include <sys/types.h> |
|
54 # include <sys/wait.h> |
|
55 #endif |
|
56 |
|
57 Q_DECLARE_METATYPE(QRect) |
|
58 |
|
59 |
|
60 #if defined(Q_OS_WIN32) |
|
61 # define ACCEPTABLE_WINDOWS |
|
62 #endif |
|
63 |
|
64 |
|
65 //TESTED_CLASS= |
|
66 //TESTED_FILES= |
|
67 |
|
68 class tst_QPrinterInfo : public QObject |
|
69 { |
|
70 Q_OBJECT |
|
71 |
|
72 public: |
|
73 //tst_QPrinterInfo(); |
|
74 //virtual ~tst_QPrinterInfo(); |
|
75 |
|
76 |
|
77 public slots: |
|
78 //void initTestCase(); |
|
79 //void cleanupTestCase(); |
|
80 //void init(); |
|
81 //void cleanup(); |
|
82 private slots: |
|
83 void testForDefaultPrinter(); |
|
84 void testForPrinters(); |
|
85 void testForPaperSizes(); |
|
86 void testConstructors(); |
|
87 void testAssignment(); |
|
88 |
|
89 private: |
|
90 void macFixNameFormat(QString *printerName); |
|
91 QString getDefaultPrinterFromSystem(); |
|
92 QStringList getPrintersFromSystem(); |
|
93 |
|
94 QString getOutputFromCommand(const QStringList& command); |
|
95 }; |
|
96 |
|
97 void tst_QPrinterInfo::macFixNameFormat(QString *printerName) |
|
98 { |
|
99 // Modify the format of the printer name to match Qt, lpstat returns |
|
100 // foo___domain_no, Qt returns foo @ domain.no |
|
101 #ifdef Q_WS_MAC |
|
102 printerName->replace(QLatin1String("___"), QLatin1String(" @ ")); |
|
103 printerName->replace(QLatin1String("_"), QLatin1String(".")); |
|
104 #else |
|
105 Q_UNUSED(printerName); |
|
106 #endif |
|
107 } |
|
108 |
|
109 QString tst_QPrinterInfo::getDefaultPrinterFromSystem() |
|
110 { |
|
111 QStringList command; |
|
112 command << "lpstat" << "-d"; |
|
113 QString output = getOutputFromCommand(command); |
|
114 |
|
115 QRegExp noDefaultReg("[^:]*no .*default"); |
|
116 int pos = noDefaultReg.indexIn(output); |
|
117 if (pos >= 0) { |
|
118 return QString(); |
|
119 } |
|
120 |
|
121 QRegExp defaultReg("default.*: *([a-zA-Z0-9_]+)"); |
|
122 defaultReg.indexIn(output); |
|
123 QString printer = defaultReg.cap(1); |
|
124 macFixNameFormat(&printer); |
|
125 return printer; |
|
126 } |
|
127 |
|
128 QStringList tst_QPrinterInfo::getPrintersFromSystem() |
|
129 { |
|
130 QStringList ans; |
|
131 |
|
132 QStringList command; |
|
133 command << "lpstat" << "-p"; |
|
134 QString output = getOutputFromCommand(command); |
|
135 QStringList list = output.split(QChar::fromLatin1('\n')); |
|
136 |
|
137 QRegExp reg("^[Pp]rinter ([.a-zA-Z0-9_-]+)"); |
|
138 for (int c = 0; c < list.size(); ++c) { |
|
139 if (reg.indexIn(list[c]) >= 0) { |
|
140 QString printer = reg.cap(1); |
|
141 macFixNameFormat(&printer); |
|
142 ans << printer; |
|
143 } |
|
144 } |
|
145 |
|
146 return ans; |
|
147 } |
|
148 |
|
149 // This function does roughly the same as the `command substitution` in |
|
150 // the shell. |
|
151 QString tst_QPrinterInfo::getOutputFromCommand(const QStringList& command) |
|
152 { |
|
153 // The command execution does nothing on non-unix systems. |
|
154 #ifdef Q_OS_UNIX |
|
155 int pid; |
|
156 int status = 0; |
|
157 int pipePtr[2]; |
|
158 |
|
159 // Create a pipe that is shared between parent and child process. |
|
160 if (pipe(pipePtr) < 0) { |
|
161 return QString(); |
|
162 } |
|
163 pid = fork(); |
|
164 if (pid < 0) { |
|
165 close(pipePtr[0]); |
|
166 close(pipePtr[1]); |
|
167 return QString(); |
|
168 } else if (pid == 0) { |
|
169 // In child. |
|
170 // Close the reading end. |
|
171 close(pipePtr[0]); |
|
172 // Redirect stdout to the pipe. |
|
173 if (dup2(pipePtr[1], 1) < 0) { |
|
174 exit(1); |
|
175 } |
|
176 |
|
177 char** argv = new char*[command.size()+1]; |
|
178 for (int c = 0; c < command.size(); ++c) { |
|
179 argv[c] = new char[command[c].size()+1]; |
|
180 strcpy(argv[c], command[c].toLatin1().data()); |
|
181 } |
|
182 argv[command.size()] = NULL; |
|
183 execvp(argv[0], argv); |
|
184 // Shouldn't get here, but it's possible if command is not found. |
|
185 close(pipePtr[1]); |
|
186 close(1); |
|
187 for (int c = 0; c < command.size(); ++c) { |
|
188 delete [] argv[c]; |
|
189 } |
|
190 delete [] argv; |
|
191 exit(1); |
|
192 } else { |
|
193 // In parent. |
|
194 // Close the writing end. |
|
195 close(pipePtr[1]); |
|
196 |
|
197 QFile pipeRead; |
|
198 if (!pipeRead.open(pipePtr[0], QIODevice::ReadOnly)) { |
|
199 close(pipePtr[0]); |
|
200 return QString(); |
|
201 } |
|
202 QByteArray array; |
|
203 array = pipeRead.readAll(); |
|
204 pipeRead.close(); |
|
205 close(pipePtr[0]); |
|
206 wait(&status); |
|
207 return QString(array); |
|
208 } |
|
209 #else |
|
210 return QString(); |
|
211 #endif // Q_OS_UNIX |
|
212 } |
|
213 |
|
214 void tst_QPrinterInfo::testForDefaultPrinter() |
|
215 { |
|
216 #if defined(Q_OS_UNIX) || defined(ACCEPTABLE_WINDOWS) |
|
217 # ifdef ACCEPTABLE_WINDOWS |
|
218 if (QHostInfo::localHostName() == "fantomet" || QHostInfo::localHostName() == "bobo") { |
|
219 QWARN("Test is hardcoded to \"fantomet\" and \"bobo\" on Windows and may fail"); |
|
220 } else { |
|
221 QSKIP("Test is hardcoded to \"fantomet\" and \"bobo\" on Windows", SkipAll); |
|
222 } |
|
223 QString defSysPrinter; |
|
224 if (QHostInfo::localHostName() == "fantomet") { |
|
225 defSysPrinter = "Yacc (Lexmark Optra T610 PS3)"; |
|
226 } else if (QHostInfo::localHostName() == "bobo") { |
|
227 defSysPrinter = "press"; |
|
228 } |
|
229 # else |
|
230 QString defSysPrinter = getDefaultPrinterFromSystem(); |
|
231 # endif |
|
232 if (defSysPrinter == "") return; |
|
233 |
|
234 QList<QPrinterInfo> list = QPrinterInfo::availablePrinters(); |
|
235 bool found = false; |
|
236 for (int c = 0; c < list.size(); ++c) { |
|
237 if (list[c].isDefault()) { |
|
238 QVERIFY(list.at(c).printerName() == defSysPrinter); |
|
239 QVERIFY(!list.at(c).isNull()); |
|
240 found = true; |
|
241 } else { |
|
242 QVERIFY(list.at(c).printerName() != defSysPrinter); |
|
243 QVERIFY(!list.at(c).isNull()); |
|
244 } |
|
245 } |
|
246 |
|
247 if (!found && defSysPrinter != "") QFAIL("No default printer reported by Qt, although there is one"); |
|
248 #else |
|
249 QSKIP("Test doesn't work on non-Unix", SkipAll); |
|
250 #endif // defined(Q_OS_UNIX) || defined(ACCEPTABLE_WINDOWS) |
|
251 } |
|
252 |
|
253 void tst_QPrinterInfo::testForPrinters() |
|
254 { |
|
255 #if defined(Q_OS_UNIX) || defined(ACCEPTABLE_WINDOWS) |
|
256 # ifdef ACCEPTABLE_WINDOWS |
|
257 if (QHostInfo::localHostName() == "fantomet" || QHostInfo::localHostName() == "bobo") { |
|
258 QWARN("Test is hardcoded to \"fantomet\" and \"bobo\" on Windows and may fail"); |
|
259 } else { |
|
260 QSKIP("Test is hardcoded to \"fantomet\" and \"bobo\" on Windows", SkipAll); |
|
261 } |
|
262 QStringList sysPrinters; |
|
263 if (QHostInfo::localHostName() == "fantomet") { |
|
264 sysPrinters |
|
265 << "Press" |
|
266 << "Canon PS-IPU Color Laser Copier v52.3" |
|
267 << "EPSON EPL-N4000 PS3" |
|
268 << "Kroksleiven" |
|
269 << "Lexmark Optra Color 1200 PS" |
|
270 << "Yacc (Lexmark Optra T610 PCL)" |
|
271 << "Yacc (Lexmark Optra T610 PS3)" |
|
272 ; |
|
273 } else if (QHostInfo::localHostName() == "bobo") { |
|
274 sysPrinters |
|
275 << "press" |
|
276 << "finnmarka" |
|
277 << "nordmarka" |
|
278 ; |
|
279 } |
|
280 # else |
|
281 QStringList sysPrinters = getPrintersFromSystem(); |
|
282 # endif |
|
283 QList<QPrinterInfo> printers = QPrinterInfo::availablePrinters(); |
|
284 |
|
285 QCOMPARE(printers.size(), sysPrinters.size()); |
|
286 |
|
287 QHash<QString, bool> qtPrinters; |
|
288 |
|
289 for (int j = 0; j < printers.size(); ++j) { |
|
290 qtPrinters.insert(printers.at(j).printerName(), !printers.at(j).isNull()); |
|
291 } |
|
292 |
|
293 for (int i = 0; i < sysPrinters.size(); ++i) { |
|
294 if (!qtPrinters.value(sysPrinters.at(i))) { |
|
295 qDebug() << "Avaliable printers: " << qtPrinters; |
|
296 QFAIL(qPrintable(QString("Printer '%1' reported by system, but not reported by Qt").arg(sysPrinters.at(i)))); |
|
297 } |
|
298 } |
|
299 #else |
|
300 QSKIP("Test doesn't work on non-Unix", SkipAll); |
|
301 #endif // defined(Q_OS_UNIX) || defined(ACCEPTABLE_WINDOWS) |
|
302 } |
|
303 |
|
304 void tst_QPrinterInfo::testForPaperSizes() |
|
305 { |
|
306 QSKIP("PaperSize feature doesn't work on Windows, fails on Mac, and is unstable on Linux", SkipAll); |
|
307 // This test is based on common printers found at the Oslo |
|
308 // office. It is likely to be skipped or fail for other locations. |
|
309 QStringList hardPrinters; |
|
310 hardPrinters << "Finnmarka" << "Huldra"; |
|
311 |
|
312 QList<QList<QPrinter::PaperSize> > hardSizes; |
|
313 hardSizes |
|
314 << QList<QPrinter::PaperSize>() |
|
315 << QList<QPrinter::PaperSize>() |
|
316 ; |
|
317 hardSizes[0] // Finnmarka |
|
318 << QPrinter::Letter |
|
319 << QPrinter::A4 |
|
320 << QPrinter::A3 |
|
321 << QPrinter::A5 |
|
322 << QPrinter::B4 |
|
323 << QPrinter::B5 |
|
324 << QPrinter::Custom // COM10 |
|
325 << QPrinter::Custom // C5 |
|
326 << QPrinter::Custom // DL |
|
327 << QPrinter::Custom // Monarch |
|
328 << QPrinter::Executive |
|
329 << QPrinter::Custom // Foolscap |
|
330 << QPrinter::Custom // ISO B5 |
|
331 << QPrinter::Ledger |
|
332 << QPrinter::Legal |
|
333 << QPrinter::Custom // Japanese Post Card |
|
334 << QPrinter::Custom // Invoice |
|
335 ; |
|
336 hardSizes[1] // Huldra |
|
337 << QPrinter::Custom // Not listed at http://localhost:631/, name "Custom" |
|
338 << QPrinter::Letter |
|
339 << QPrinter::A4 |
|
340 << QPrinter::A5 |
|
341 << QPrinter::A6 |
|
342 << QPrinter::B5 |
|
343 << QPrinter::Custom // #5 1/2 Envelope |
|
344 << QPrinter::Custom // 6x9 Envelope |
|
345 << QPrinter::Custom // #10 Envelope |
|
346 << QPrinter::Custom // A7 Envelope |
|
347 << QPrinter::Custom // C5 Envelope |
|
348 << QPrinter::Custom // DL Envelope |
|
349 << QPrinter::Custom // Monarch Envelope |
|
350 << QPrinter::Custom // #6 3/4 Envelope |
|
351 << QPrinter::Executive |
|
352 << QPrinter::Custom // US Folio |
|
353 << QPrinter::Custom // Index Card |
|
354 << QPrinter::Custom // ISO B5 |
|
355 << QPrinter::Legal |
|
356 << QPrinter::Custom // Statement |
|
357 ; |
|
358 |
|
359 QList<QPrinterInfo> printers = QPrinterInfo::availablePrinters(); |
|
360 for (int i = 0; i < printers.size(); ++i) { |
|
361 for (int j = 0; j < hardPrinters.size(); ++j) { |
|
362 if (printers[i].printerName() == hardPrinters[j]) { |
|
363 QList<QPrinter::PaperSize> sizes = printers[i].supportedPaperSizes(); |
|
364 qSort(sizes); |
|
365 qSort(hardSizes[j]); |
|
366 QCOMPARE(sizes, hardSizes[j]); |
|
367 } |
|
368 } |
|
369 } |
|
370 } |
|
371 |
|
372 void tst_QPrinterInfo::testConstructors() |
|
373 { |
|
374 QList<QPrinterInfo> prns(QPrinterInfo::availablePrinters()); |
|
375 |
|
376 for (int c = 0; c < prns.size(); ++c) { |
|
377 QList<QPrinter::PaperSize> list1, list2; |
|
378 list1 = prns[c].supportedPaperSizes(); |
|
379 QPrinter pr(prns[c]); |
|
380 list2 = QPrinterInfo(pr).supportedPaperSizes(); |
|
381 QCOMPARE(list2, list1); |
|
382 } |
|
383 } |
|
384 |
|
385 void tst_QPrinterInfo::testAssignment() |
|
386 { |
|
387 QList<QPrinterInfo> prns(QPrinterInfo::availablePrinters()); |
|
388 |
|
389 for (int c = 0; c < prns.size(); ++c) { |
|
390 QPrinterInfo pi = QPrinterInfo::defaultPrinter(); |
|
391 pi = prns[c]; |
|
392 QCOMPARE(pi.printerName(), prns[c].printerName()); |
|
393 QCOMPARE(pi.supportedPaperSizes(), prns[c].supportedPaperSizes()); |
|
394 } |
|
395 } |
|
396 |
|
397 QTEST_MAIN(tst_QPrinterInfo) |
|
398 #include "tst_qprinterinfo.moc" |
|
399 #else |
|
400 QTEST_NOOP_MAIN |
|
401 #endif |