1/****************************************************************************
2**
3** Copyright (C) 2018 The Qt Company Ltd.
4** Contact: https://www.qt.io/licensing/
5**
6** This file is part of the test suite of the Qt Toolkit.
7**
8** $QT_BEGIN_LICENSE:GPL-EXCEPT$
9** Commercial License Usage
10** Licensees holding valid commercial Qt licenses may use this file in
11** accordance with the commercial license agreement provided with the
12** Software or, alternatively, in accordance with the terms contained in
13** a written agreement between you and The Qt Company. For licensing terms
14** and conditions see https://www.qt.io/terms-conditions. For further
15** information use the contact form at https://www.qt.io/contact-us.
16**
17** GNU General Public License Usage
18** Alternatively, this file may be used under the terms of the GNU
19** General Public License version 3 as published by the Free Software
20** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
21** included in the packaging of this file. Please review the following
22** information to ensure the GNU General Public License requirements will
23** be met: https://www.gnu.org/licenses/gpl-3.0.html.
24**
25** $QT_END_LICENSE$
26**
27****************************************************************************/
28
29
30#include <QtTest/QtTest>
31#include <QtSql/QtSql>
32#include <QTableView>
33#include <QComboBox>
34
35#include "../../kernel/qsqldatabase/tst_databases.h"
36
37const QString reltest1(qTableName(prefix: "reltest1", __FILE__, db: QSqlDatabase())),
38 reltest2(qTableName(prefix: "reltest2", __FILE__, db: QSqlDatabase()));
39
40class tst_QSqlRelationalDelegate : public QObject
41{
42 Q_OBJECT
43
44public:
45 void recreateTestTables(QSqlDatabase);
46
47 tst_Databases dbs;
48
49public slots:
50 void initTestCase_data();
51 void initTestCase();
52 void cleanupTestCase();
53 void init();
54 void cleanup();
55
56private slots:
57 void comboBoxEditor();
58private:
59 void dropTestTables(QSqlDatabase db);
60};
61
62
63void tst_QSqlRelationalDelegate::initTestCase_data()
64{
65 QVERIFY(dbs.open());
66 if (dbs.fillTestTable() == 0)
67 QSKIP("No database drivers are available in this Qt configuration");
68}
69
70void tst_QSqlRelationalDelegate::recreateTestTables(QSqlDatabase db)
71{
72 dropTestTables(db);
73
74 QSqlQuery q(db);
75 QVERIFY_SQL(q, exec("create table " + reltest1 +
76 " (id int not null primary key, name varchar(20), title_key int, another_title_key int)"));
77 QVERIFY_SQL(q, exec("insert into " + reltest1 + " values(1, 'harry', 1, 2)"));
78 QVERIFY_SQL(q, exec("insert into " + reltest1 + " values(2, 'trond', 2, 1)"));
79 QVERIFY_SQL(q, exec("insert into " + reltest1 + " values(3, 'vohi', 1, 2)"));
80 QVERIFY_SQL(q, exec("insert into " + reltest1 + " values(4, 'boris', 2, 2)"));
81 QVERIFY_SQL(q, exec("insert into " + reltest1 + " values(5, 'nat', NULL, NULL)"));
82 QVERIFY_SQL(q, exec("insert into " + reltest1 + " values(6, 'ale', NULL, 2)"));
83
84 QVERIFY_SQL(q, exec("create table " + reltest2 + " (id int not null primary key, title varchar(20))"));
85 QVERIFY_SQL(q, exec("insert into " + reltest2 + " values(1, 'herr')"));
86 QVERIFY_SQL(q, exec("insert into " + reltest2 + " values(2, 'mister')"));
87}
88
89void tst_QSqlRelationalDelegate::initTestCase()
90{
91 foreach (const QString &dbname, dbs.dbNames) {
92 QSqlDatabase db=QSqlDatabase::database(connectionName: dbname);
93 QSqlDriver::DbmsType dbType = tst_Databases::getDatabaseType(db);
94 if (dbType == QSqlDriver::Interbase) {
95 db.exec(query: "SET DIALECT 3");
96 } else if (dbType == QSqlDriver::MSSqlServer) {
97 db.exec(query: "SET ANSI_DEFAULTS ON");
98 db.exec(query: "SET IMPLICIT_TRANSACTIONS OFF");
99 } else if (dbType == QSqlDriver::PostgreSQL) {
100 db.exec(query: "set client_min_messages='warning'");
101 }
102 recreateTestTables(db);
103 }
104}
105
106void tst_QSqlRelationalDelegate::cleanupTestCase()
107{
108 foreach (const QString &dbName, dbs.dbNames) {
109 QSqlDatabase db = QSqlDatabase::database(connectionName: dbName);
110 CHECK_DATABASE(db);
111 dropTestTables(db: QSqlDatabase::database(connectionName: dbName));
112 }
113 dbs.close();
114}
115
116void tst_QSqlRelationalDelegate::dropTestTables(QSqlDatabase db)
117{
118 QStringList tableNames = { reltest1, reltest2 };
119 tst_Databases::safeDropTables(db, tableNames);
120}
121
122void tst_QSqlRelationalDelegate::init()
123{
124}
125
126void tst_QSqlRelationalDelegate::cleanup()
127{
128}
129
130void tst_QSqlRelationalDelegate::comboBoxEditor()
131{
132 QFETCH_GLOBAL(QString, dbName);
133 QSqlDatabase db = QSqlDatabase::database(connectionName: dbName);
134 CHECK_DATABASE(db);
135
136 QTableView tv;
137 QSqlRelationalTableModel model(0, db);
138 model.setEditStrategy(QSqlTableModel::OnManualSubmit);
139 model.setTable(reltest1);
140 model.setRelation(column: 2, relation: QSqlRelation(reltest2, "id", "title"));
141 model.setRelation(column: 3, relation: QSqlRelation(reltest2, "id", "title"));
142 tv.setModel(&model);
143 QVERIFY_SQL(model, select());
144
145 QSqlRelationalDelegate delegate;
146 tv.setItemDelegate(&delegate);
147 tv.show();
148 QVERIFY(QTest::qWaitForWindowActive(&tv));
149
150 QModelIndex index = model.index(row: 0, column: 2);
151 tv.setCurrentIndex(index);
152 tv.edit(index);
153 QList<QComboBox*> comboBoxes = tv.viewport()->findChildren<QComboBox *>();
154 QCOMPARE(comboBoxes.count(), 1);
155
156 QComboBox *editor = comboBoxes.at(i: 0);
157 QCOMPARE(editor->currentText(), "herr");
158 QTest::keyClick(widget: editor, key: Qt::Key_Down);
159 QTest::keyClick(widget: editor, key: Qt::Key_Enter);
160 QCOMPARE(editor->currentText(), "mister");
161 QTest::keyClick(widget: tv.viewport(), key: Qt::Key_Tab);
162 QVERIFY_SQL(model, submitAll());
163
164 QSqlQuery qry(db);
165 QVERIFY_SQL(qry, exec("SELECT title_key FROM " + reltest1 + " WHERE id=1"));
166 QVERIFY(qry.next());
167 QCOMPARE(qry.value(0).toString(), "2");
168}
169
170QTEST_MAIN(tst_QSqlRelationalDelegate)
171#include "tst_qsqlrelationaldelegate.moc"
172

source code of qtbase/tests/auto/sql/models/qsqlrelationaldelegate/tst_qsqlrelationaldelegate.cpp