sqlitestatement-test.cpp 20.2 KB
Newer Older
1 2
/****************************************************************************
**
3 4
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
5 6 7 8 9 10 11
**
** This file is part of Qt Creator.
**
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
12 13 14
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
15
**
16 17 18 19 20 21 22
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
23 24 25
**
****************************************************************************/

Marco Bubke's avatar
Marco Bubke committed
26
#include "googletest.h"
Marco Bubke's avatar
Marco Bubke committed
27
#include "mocksqlitestatement.h"
28
#include "sqliteteststatement.h"
Marco Bubke's avatar
Marco Bubke committed
29

30
#include <sqlitedatabase.h>
Marco Bubke's avatar
Marco Bubke committed
31 32 33
#include <sqlitereadstatement.h>
#include <sqlitereadwritestatement.h>
#include <sqlitewritestatement.h>
34

Marco Bubke's avatar
Marco Bubke committed
35 36
#include <utils/smallstringio.h>

Marco Bubke's avatar
Marco Bubke committed
37
#include <QDir>
38 39

#include <vector>
40 41

namespace {
42

Marco Bubke's avatar
Marco Bubke committed
43
using Sqlite::JournalMode;
44 45 46 47 48
using Sqlite::Exception;
using Sqlite::Database;
using Sqlite::ReadStatement;
using Sqlite::ReadWriteStatement;
using Sqlite::WriteStatement;
Marco Bubke's avatar
Marco Bubke committed
49

50 51 52 53 54 55 56
MATCHER_P3(HasValues, value1, value2, rowid,
           std::string(negation ? "isn't" : "is")
           + PrintToString(value1)
           + ", " + PrintToString(value2)
           + " and " + PrintToString(rowid)
           )
{
57
    Database &database = arg.database();
58

59
    SqliteTestStatement statement("SELECT name, number FROM test WHERE rowid=?", database);
60 61 62 63
    statement.bind(1, rowid);

    statement.next();

64 65
    return statement.fetchSmallStringViewValue(0) == value1
        && statement.fetchSmallStringViewValue(1) == value2;
66 67
}

68 69 70 71 72 73
class SqliteStatement : public ::testing::Test
{
protected:
     void SetUp() override;
     void TearDown() override;

74
protected:
Marco Bubke's avatar
Marco Bubke committed
75
     Database database{":memory:", Sqlite::JournalMode::Memory};
76 77
};

Marco Bubke's avatar
Marco Bubke committed
78 79
struct Output
{
80
    Output(Utils::SmallStringView name, Utils::SmallStringView number, long long value)
81 82 83
        : name(name), number(number), value(value)
    {}

Marco Bubke's avatar
Marco Bubke committed
84 85 86 87 88 89 90 91 92 93 94 95 96
    Utils::SmallString name;
    Utils::SmallString number;
    long long value;
    friend bool operator==(const Output &f, const Output &s)
    {
        return f.name == s.name && f.number == s.number && f.value == s.value;
    }
    friend std::ostream &operator<<(std::ostream &out, const Output &o)
    {
        return out << "(" << o.name << ", " << ", " << o.number<< ", " << o.value<< ")";
    }
};

97
TEST_F(SqliteStatement, ThrowsStatementHasErrorForWrongSqlStatement)
98
{
99 100 101 102 103 104 105 106 107 108 109 110 111
    ASSERT_THROW(ReadStatement("blah blah blah", database), Sqlite::StatementHasError);
}

TEST_F(SqliteStatement, ThrowsNotReadOnlySqlStatementForWritableSqlStatementInReadStatement)
{
    ASSERT_THROW(ReadStatement("INSERT INTO test(name, number) VALUES (?, ?)", database),
                 Sqlite::NotReadOnlySqlStatement);
}

TEST_F(SqliteStatement, ThrowsNotReadonlySqlStatementForWritableSqlStatementInReadStatement)
{
    ASSERT_THROW(WriteStatement("SELECT name, number FROM test", database),
                 Sqlite::NotWriteSqlStatement);
112 113 114 115
}

TEST_F(SqliteStatement, CountRows)
{
116
    SqliteTestStatement statement("SELECT * FROM test", database);
117 118 119 120
    int nextCount = 0;
    while (statement.next())
        ++nextCount;

121
    int sqlCount = ReadStatement::toValue<int>("SELECT count(*) FROM test", database);
122 123 124 125 126 127

    ASSERT_THAT(nextCount, sqlCount);
}

TEST_F(SqliteStatement, Value)
{
128
    SqliteTestStatement statement("SELECT name, number FROM test ORDER BY name", database);
129 130 131 132
    statement.next();

    statement.next();

133 134 135
    ASSERT_THAT(statement.fetchValue<int>(0), 0);
    ASSERT_THAT(statement.fetchValue<int64_t>(0), 0);
    ASSERT_THAT(statement.fetchValue<double>(0), 0.0);
136 137 138
    ASSERT_THAT(statement.fetchValue<Utils::SmallString>(0), "foo");
    ASSERT_THAT(statement.fetchValue<Utils::PathString>(0), "foo");
    ASSERT_THAT(statement.fetchSmallStringViewValue(0), "foo");
139 140 141
    ASSERT_THAT(statement.fetchValue<int>(1), 23);
    ASSERT_THAT(statement.fetchValue<int64_t>(1), 23);
    ASSERT_THAT(statement.fetchValue<double>(1), 23.3);
142 143 144
    ASSERT_THAT(statement.fetchValue<Utils::SmallString>(1), "23.3");
    ASSERT_THAT(statement.fetchValue<Utils::PathString>(1), "23.3");
    ASSERT_THAT(statement.fetchSmallStringViewValue(1), "23.3");
145 146
}

147
TEST_F(SqliteStatement, ThrowNoValuesToFetchForNotSteppedStatement)
148
{
149
    SqliteTestStatement statement("SELECT name, number FROM test", database);
150

151
    ASSERT_THROW(statement.fetchValue<int>(0), Sqlite::NoValuesToFetch);
152
}
153

154 155
TEST_F(SqliteStatement, ThrowNoValuesToFetchForDoneStatement)
{
156
    SqliteTestStatement statement("SELECT name, number FROM test", database);
157 158
    while (statement.next()) {}

159
    ASSERT_THROW(statement.fetchValue<int>(0), Sqlite::NoValuesToFetch);
160
}
161

162 163
TEST_F(SqliteStatement, ThrowInvalidColumnFetchedForNegativeColumn)
{
164
    SqliteTestStatement statement("SELECT name, number FROM test", database);
165
    statement.next();
166

167
    ASSERT_THROW(statement.fetchValue<int>(-1), Sqlite::InvalidColumnFetched);
168 169 170 171
}

TEST_F(SqliteStatement, ThrowInvalidColumnFetchedForNotExistingColumn)
{
172
    SqliteTestStatement statement("SELECT name, number FROM test", database);
173 174
    statement.next();

175
    ASSERT_THROW(statement.fetchValue<int>(2), Sqlite::InvalidColumnFetched);
176 177 178 179
}

TEST_F(SqliteStatement, ToIntergerValue)
{
180
    auto value = ReadStatement::toValue<int>("SELECT number FROM test WHERE name='foo'", database);
Marco Bubke's avatar
Marco Bubke committed
181 182

    ASSERT_THAT(value, 23);
183 184 185 186
}

TEST_F(SqliteStatement, ToLongIntergerValue)
{
187
    ASSERT_THAT(ReadStatement::toValue<qint64>("SELECT number FROM test WHERE name='foo'", database), Eq(23));
188 189 190 191
}

TEST_F(SqliteStatement, ToDoubleValue)
{
192
    ASSERT_THAT(ReadStatement::toValue<double>("SELECT number FROM test WHERE name='foo'", database), 23.3);
193 194
}

195
TEST_F(SqliteStatement, ToStringValue)
196
{
197
    ASSERT_THAT(ReadStatement::toValue<Utils::SmallString>("SELECT name FROM test WHERE name='foo'", database), "foo");
198 199 200 201
}

TEST_F(SqliteStatement, ColumnNames)
{
202
    SqliteTestStatement statement("SELECT name, number FROM test", database);
203

204
    auto columnNames = statement.columnNames();
205

206
    ASSERT_THAT(columnNames, ElementsAre("name", "number"));
207 208
}

209
TEST_F(SqliteStatement, BindString)
210 211
{

212
    SqliteTestStatement statement("SELECT name, number FROM test WHERE name=?", database);
213

214
    statement.bind(1, "foo");
215 216 217

    statement.next();

218
    ASSERT_THAT(statement.fetchSmallStringViewValue(0), "foo");
219
    ASSERT_THAT(statement.fetchValue<double>(1), 23.3);
220 221 222 223
}

TEST_F(SqliteStatement, BindInteger)
{
224
    SqliteTestStatement statement("SELECT name, number FROM test WHERE number=?", database);
225 226 227 228

    statement.bind(1, 40);
    statement.next();

229
    ASSERT_THAT(statement.fetchSmallStringViewValue(0),"poo");
230 231 232 233
}

TEST_F(SqliteStatement, BindLongInteger)
{
234
    SqliteTestStatement statement("SELECT name, number FROM test WHERE number=?", database);
235

Marco Bubke's avatar
Marco Bubke committed
236
    statement.bind(1, int64_t(40));
237 238
    statement.next();

239
    ASSERT_THAT(statement.fetchSmallStringViewValue(0), "poo");
240 241 242 243
}

TEST_F(SqliteStatement, BindDouble)
{
244
    SqliteTestStatement statement("SELECT name, number FROM test WHERE number=?", database);
245 246 247 248

    statement.bind(1, 23.3);
    statement.next();

249
    ASSERT_THAT(statement.fetchSmallStringViewValue(0), "foo");
250 251 252 253
}

TEST_F(SqliteStatement, BindIntegerByParameter)
{
254
    SqliteTestStatement statement("SELECT name, number FROM test WHERE number=@number", database);
255

256
    statement.bind("@number", 40);
257 258
    statement.next();

259
    ASSERT_THAT(statement.fetchSmallStringViewValue(0), "poo");
260 261 262 263
}

TEST_F(SqliteStatement, BindLongIntegerByParameter)
{
264
    SqliteTestStatement statement("SELECT name, number FROM test WHERE number=@number", database);
265

Marco Bubke's avatar
Marco Bubke committed
266
    statement.bind("@number", int64_t(40));
267 268
    statement.next();

269
    ASSERT_THAT(statement.fetchSmallStringViewValue(0), "poo");
270 271 272 273
}

TEST_F(SqliteStatement, BindDoubleByIndex)
{
274
    SqliteTestStatement statement("SELECT name, number FROM test WHERE number=@number", database);
275

276
    statement.bind(statement.bindingIndexForName("@number"), 23.3);
277 278
    statement.next();

279
    ASSERT_THAT(statement.fetchSmallStringViewValue(0), "foo");
280 281
}

282
TEST_F(SqliteStatement, BindIndexIsZeroIsThrowingBindingIndexIsOutOfBound)
283
{
284
    SqliteTestStatement statement("SELECT name, number FROM test WHERE number=$1", database);
285

286 287 288 289 290
    ASSERT_THROW(statement.bind(0, 40), Sqlite::BindingIndexIsOutOfRange);
}

TEST_F(SqliteStatement, BindIndexIsTpLargeIsThrowingBindingIndexIsOutOfBound)
{
291
    SqliteTestStatement statement("SELECT name, number FROM test WHERE number=$1", database);
292 293 294 295 296 297

    ASSERT_THROW(statement.bind(2, 40), Sqlite::BindingIndexIsOutOfRange);
}

TEST_F(SqliteStatement, WrongBindingNameThrowingBindingIndexIsOutOfBound)
{
298
    SqliteTestStatement statement("SELECT name, number FROM test WHERE number=@name", database);
299

Marco Bubke's avatar
Marco Bubke committed
300
    ASSERT_THROW(statement.bind("@name2", 40), Sqlite::WrongBindingName);
301 302
}

303 304
TEST_F(SqliteStatement, BindValues)
{
305
    SqliteTestStatement statement("UPDATE test SET name=?, number=? WHERE rowid=?", database);
306 307 308 309 310 311 312 313 314

    statement.bindValues("see", 7.23, 1);
    statement.execute();

    ASSERT_THAT(statement, HasValues("see", "7.23", 1));
}

TEST_F(SqliteStatement, WriteValues)
{
315
    WriteStatement statement("UPDATE test SET name=?, number=? WHERE rowid=?", database);
316 317 318 319 320 321 322 323

    statement.write("see", 7.23, 1);

    ASSERT_THAT(statement, HasValues("see", "7.23", 1));
}

TEST_F(SqliteStatement, BindNamedValues)
{
324
    SqliteTestStatement statement("UPDATE test SET name=@name, number=@number WHERE rowid=@id", database);
325 326 327 328 329 330 331 332 333

    statement.bindNameValues("@name", "see", "@number", 7.23, "@id", 1);
    statement.execute();

    ASSERT_THAT(statement, HasValues("see", "7.23", 1));
}

TEST_F(SqliteStatement, WriteNamedValues)
{
334
    WriteStatement statement("UPDATE test SET name=@name, number=@number WHERE rowid=@id", database);
335 336 337 338 339 340

    statement.writeNamed("@name", "see", "@number", 7.23, "@id", 1);

    ASSERT_THAT(statement, HasValues("see", "7.23", 1));
}

341 342 343 344 345 346 347 348 349
TEST_F(SqliteStatement, CannotWriteToClosedDatabase)
{
    database.close();

    ASSERT_THROW(WriteStatement("INSERT INTO test(name, number) VALUES (?, ?)", database),
                 Sqlite::DatabaseIsNotOpen);
}

TEST_F(SqliteStatement, CannotReadFromClosedDatabase)
350
{
351
    database.close();
352 353 354

    ASSERT_THROW(ReadStatement("SELECT * FROM test", database),
                 Sqlite::DatabaseIsNotOpen);
355 356
}

Marco Bubke's avatar
Marco Bubke committed
357 358 359
TEST_F(SqliteStatement, GetTupleValuesWithoutArguments)
{
    using Tuple = std::tuple<Utils::SmallString, double, int>;
360
    ReadStatement statement("SELECT name, number, value FROM test", database);
Marco Bubke's avatar
Marco Bubke committed
361

362
    auto values = statement.values<Tuple, 3>(3);
Marco Bubke's avatar
Marco Bubke committed
363 364 365 366 367 368 369 370

    ASSERT_THAT(values, ElementsAre(Tuple{"bar", 0, 1},
                                    Tuple{"foo", 23.3, 2},
                                    Tuple{"poo", 40.0, 3}));
}

TEST_F(SqliteStatement, GetSingleValuesWithoutArguments)
{
371
    ReadStatement statement("SELECT name FROM test", database);
Marco Bubke's avatar
Marco Bubke committed
372 373 374 375 376 377 378 379

    std::vector<Utils::SmallString> values = statement.values<Utils::SmallString>(3);

    ASSERT_THAT(values, ElementsAre("bar", "foo", "poo"));
}

TEST_F(SqliteStatement, GetStructValuesWithoutArguments)
{
380
    ReadStatement statement("SELECT name, number, value FROM test", database);
Marco Bubke's avatar
Marco Bubke committed
381

382
    auto values = statement.values<Output, 3>(3);
Marco Bubke's avatar
Marco Bubke committed
383 384 385 386 387 388 389 390

    ASSERT_THAT(values, ElementsAre(Output{"bar", "blah", 1},
                                    Output{"foo", "23.3", 2},
                                    Output{"poo", "40", 3}));
}

TEST_F(SqliteStatement, GetValuesForSingleOutputWithBindingMultipleTimes)
{
391
    ReadStatement statement("SELECT name FROM test WHERE number=?", database);
Marco Bubke's avatar
Marco Bubke committed
392 393 394 395 396 397 398 399 400 401 402
    statement.values<Utils::SmallString>(3, 40);

    std::vector<Utils::SmallString> values = statement.values<Utils::SmallString>(3, 40);

    ASSERT_THAT(values, ElementsAre("poo"));
}

TEST_F(SqliteStatement, GetValuesForMultipleOutputValuesAndContainerQueryValues)
{
    using Tuple = std::tuple<Utils::SmallString, double, double>;
    std::vector<double> queryValues = {40, 23.3};
403
    ReadStatement statement("SELECT name, number, value FROM test WHERE number=?", database);
Marco Bubke's avatar
Marco Bubke committed
404

405
    auto values = statement.values<Tuple, 3>(3, queryValues);
Marco Bubke's avatar
Marco Bubke committed
406 407 408 409 410 411 412 413

    ASSERT_THAT(values, ElementsAre(Tuple{"poo", 40, 3.},
                                    Tuple{"foo", 23.3, 2.}));
}

TEST_F(SqliteStatement, GetValuesForSingleOutputValuesAndContainerQueryValues)
{
    std::vector<double> queryValues = {40, 23.3};
414
    ReadStatement statement("SELECT name, number FROM test WHERE number=?", database);
Marco Bubke's avatar
Marco Bubke committed
415 416 417 418 419 420 421 422 423

    std::vector<Utils::SmallString> values = statement.values<Utils::SmallString>(3, queryValues);

    ASSERT_THAT(values, ElementsAre("poo", "foo"));
}

TEST_F(SqliteStatement, GetValuesForMultipleOutputValuesAndContainerQueryTupleValues)
{
    using Tuple = std::tuple<Utils::SmallString, Utils::SmallString, int>;
424
    using ResultTuple = std::tuple<Utils::SmallString, double, int>;
Marco Bubke's avatar
Marco Bubke committed
425
    std::vector<Tuple> queryValues = {{"poo", "40", 3}, {"bar", "blah", 1}};
426
    ReadStatement statement("SELECT name, number, value FROM test WHERE name= ? AND number=? AND value=?", database);
Marco Bubke's avatar
Marco Bubke committed
427

428
    auto values = statement.values<ResultTuple, 3>(3, queryValues);
Marco Bubke's avatar
Marco Bubke committed
429

430 431
    ASSERT_THAT(values, ElementsAre(ResultTuple{"poo", 40, 3},
                                    ResultTuple{"bar", 0, 1}));
Marco Bubke's avatar
Marco Bubke committed
432 433 434 435 436 437
}

TEST_F(SqliteStatement, GetValuesForSingleOutputValuesAndContainerQueryTupleValues)
{
    using Tuple = std::tuple<Utils::SmallString, Utils::SmallString>;
    std::vector<Tuple> queryValues = {{"poo", "40"}, {"bar", "blah"}};
438
    ReadStatement statement("SELECT name, number FROM test WHERE name= ? AND number=?", database);
Marco Bubke's avatar
Marco Bubke committed
439 440 441 442 443 444 445 446 447

    std::vector<Utils::SmallString> values = statement.values<Utils::SmallString>(3, queryValues);

    ASSERT_THAT(values, ElementsAre("poo", "bar"));
}

TEST_F(SqliteStatement, GetValuesForMultipleOutputValuesAndMultipleQueryValue)
{
    using Tuple = std::tuple<Utils::SmallString, Utils::SmallString, long long>;
448
    ReadStatement statement("SELECT name, number, value FROM test WHERE name=? AND number=? AND value=?", database);
Marco Bubke's avatar
Marco Bubke committed
449

450
    auto values = statement.values<Tuple, 3>(3, "bar", "blah", 1);
Marco Bubke's avatar
Marco Bubke committed
451 452 453 454 455 456 457

    ASSERT_THAT(values, ElementsAre(Tuple{"bar", "blah", 1}));
}

TEST_F(SqliteStatement, CallGetValuesForMultipleOutputValuesAndMultipleQueryValueMultipleTimes)
{
    using Tuple = std::tuple<Utils::SmallString, Utils::SmallString, long long>;
458
    ReadStatement statement("SELECT name, number, value FROM test WHERE name=? AND number=?", database);
459
    statement.values<Tuple, 3>(3, "bar", "blah");
Marco Bubke's avatar
Marco Bubke committed
460

461
    auto values = statement.values<Tuple, 3>(3, "bar", "blah");
Marco Bubke's avatar
Marco Bubke committed
462 463 464 465 466 467

    ASSERT_THAT(values, ElementsAre(Tuple{"bar", "blah", 1}));
}

TEST_F(SqliteStatement, GetStructOutputValuesAndMultipleQueryValue)
{
468
    ReadStatement statement("SELECT name, number, value FROM test WHERE name=? AND number=? AND value=?", database);
Marco Bubke's avatar
Marco Bubke committed
469

470
    auto values = statement.values<Output, 3>(3, "bar", "blah", 1);
Marco Bubke's avatar
Marco Bubke committed
471 472 473 474 475 476 477

    ASSERT_THAT(values, ElementsAre(Output{"bar", "blah", 1}));
}

TEST_F(SqliteStatement, GetStructOutputValuesAndContainerQueryValues)
{
    std::vector<double> queryValues = {40, 23.3};
478
    ReadStatement statement("SELECT name, number, value FROM test WHERE number=?", database);
Marco Bubke's avatar
Marco Bubke committed
479

480
    auto values = statement.values<Output, 3>(3, queryValues);
Marco Bubke's avatar
Marco Bubke committed
481 482 483 484 485 486 487 488 489

    ASSERT_THAT(values, ElementsAre(Output{"poo", "40", 3},
                                    Output{"foo", "23.3", 2}));
}

TEST_F(SqliteStatement, GetStructOutputValuesAndContainerQueryTupleValues)
{
    using Tuple = std::tuple<Utils::SmallString, Utils::SmallString, int>;
    std::vector<Tuple> queryValues = {{"poo", "40", 3}, {"bar", "blah", 1}};
490
    ReadStatement statement("SELECT name, number, value FROM test WHERE name= ? AND number=? AND value=?", database);
Marco Bubke's avatar
Marco Bubke committed
491

492
    auto values = statement.values<Output, 3>(3, queryValues);
Marco Bubke's avatar
Marco Bubke committed
493 494 495 496 497

    ASSERT_THAT(values, ElementsAre(Output{"poo", "40", 3},
                                    Output{"bar", "blah", 1}));
}

498 499 500 501 502 503 504 505 506 507 508 509 510 511 512 513 514 515 516 517 518 519 520 521 522 523 524 525
TEST_F(SqliteStatement, GetOptionalSingleValueAndMultipleQueryValue)
{
    ReadStatement statement("SELECT name FROM test WHERE name=? AND number=? AND value=?", database);

    auto value = statement.value<Utils::SmallString>("bar", "blah", 1);

    ASSERT_THAT(value.value(), Eq("bar"));
}

TEST_F(SqliteStatement, GetOptionalOutputValueAndMultipleQueryValue)
{
    ReadStatement statement("SELECT name, number, value FROM test WHERE name=? AND number=? AND value=?", database);

    auto value = statement.value<Output, 3>("bar", "blah", 1);

    ASSERT_THAT(value.value(), Eq(Output{"bar", "blah", 1}));
}

TEST_F(SqliteStatement, GetOptionalTupleValueAndMultipleQueryValue)
{
    using Tuple = std::tuple<Utils::SmallString, Utils::SmallString, long long>;
    ReadStatement statement("SELECT name, number, value FROM test WHERE name=? AND number=? AND value=?", database);

    auto value = statement.value<Tuple, 3>("bar", "blah", 1);

    ASSERT_THAT(value.value(), Eq(Tuple{"bar", "blah", 1}));
}

Marco Bubke's avatar
Marco Bubke committed
526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596 597 598 599 600 601 602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621
TEST_F(SqliteStatement, GetOptionalValueCallsReset)
{
    MockSqliteStatement mockStatement;

    EXPECT_CALL(mockStatement, reset());

    mockStatement.value<int>("bar");
}

TEST_F(SqliteStatement, GetOptionalValueCallsResetIfExceptionIsThrown)
{
    MockSqliteStatement mockStatement;
    ON_CALL(mockStatement, next()).WillByDefault(Throw(Sqlite::StatementHasError("")));

    EXPECT_CALL(mockStatement, reset());

    EXPECT_THROW(mockStatement.value<int>("bar"), Sqlite::StatementHasError);
}

TEST_F(SqliteStatement, GetValuesWithoutArgumentsCallsReset)
{
    MockSqliteStatement mockStatement;

    EXPECT_CALL(mockStatement, reset());

    mockStatement.values<int>(3);
}

TEST_F(SqliteStatement, GetValuesWithoutArgumentsCallsResetIfExceptionIsThrown)
{
    MockSqliteStatement mockStatement;
    ON_CALL(mockStatement, next()).WillByDefault(Throw(Sqlite::StatementHasError("")));

    EXPECT_CALL(mockStatement, reset());

    EXPECT_THROW(mockStatement.values<int>(3), Sqlite::StatementHasError);
}

TEST_F(SqliteStatement, GetValuesWithSimpleArgumentsCallsReset)
{
    MockSqliteStatement mockStatement;

    EXPECT_CALL(mockStatement, reset());

    mockStatement.values<int>(3, "foo", "bar");
}

TEST_F(SqliteStatement, GetValuesWithSimpleArgumentsCallsResetIfExceptionIsThrown)
{
    MockSqliteStatement mockStatement;
    ON_CALL(mockStatement, next()).WillByDefault(Throw(Sqlite::StatementHasError("")));

    EXPECT_CALL(mockStatement, reset());

    EXPECT_THROW(mockStatement.values<int>(3, "foo", "bar"), Sqlite::StatementHasError);
}

TEST_F(SqliteStatement, GetValuesWithVectorArgumentsCallsReset)
{
    MockSqliteStatement mockStatement;

    EXPECT_CALL(mockStatement, reset()).Times(2);

    mockStatement.values<int>(3, std::vector<Utils::SmallString>{"bar", "foo"});
}

TEST_F(SqliteStatement, GetValuesWithVectorArgumentCallsResetIfExceptionIsThrown)
{
    MockSqliteStatement mockStatement;
    ON_CALL(mockStatement, next()).WillByDefault(Throw(Sqlite::StatementHasError("")));

    EXPECT_CALL(mockStatement, reset());

    EXPECT_THROW(mockStatement.values<int>(3, std::vector<Utils::SmallString>{"bar", "foo"}),
                 Sqlite::StatementHasError);
}

TEST_F(SqliteStatement, GetValuesWithTupleArgumentsCallsReset)
{
    MockSqliteStatement mockStatement;

    EXPECT_CALL(mockStatement, reset()).Times(2);

    mockStatement.values<int>(3, std::vector<std::tuple<int>>{{1}, {2}});
}

TEST_F(SqliteStatement, GetValuesWithTupleArgumentsCallsResetIfExceptionIsThrown)
{
    MockSqliteStatement mockStatement;
    ON_CALL(mockStatement, next()).WillByDefault(Throw(Sqlite::StatementHasError("")));

    EXPECT_CALL(mockStatement, reset());

    EXPECT_THROW(mockStatement.values<int>(3, std::vector<std::tuple<int>>{{1}, {2}}),
                 Sqlite::StatementHasError);
}
622

623 624
void SqliteStatement::SetUp()
{
Marco Bubke's avatar
Marco Bubke committed
625 626 627 628
    database.execute("CREATE TABLE test(name TEXT UNIQUE, number NUMERIC, value NUMERIC)");
    database.execute("INSERT INTO  test VALUES ('bar', 'blah', 1)");
    database.execute("INSERT INTO  test VALUES ('foo', 23.3, 2)");
    database.execute("INSERT INTO  test VALUES ('poo', 40, 3)");
629 630 631 632
}

void SqliteStatement::TearDown()
{
633 634
    if (database.isOpen())
        database.close();
635 636 637
}

}