tests/auto/qprinterinfo/tst_qprinterinfo.cpp
changeset 0 1918ee327afb
child 4 3b1da2848fc7
equal deleted inserted replaced
-1:000000000000 0:1918ee327afb
       
     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