diff --git a/README.md b/README.md index 4ad411b5..3acf87da 100644 --- a/README.md +++ b/README.md @@ -24,7 +24,7 @@ It relies on a few libraries: Optional for the CppSpec driver. * [GMock](http://code.google.com/p/googlemock/) 1.6 or later. Optional for the internal test suite. -* [Qt 4](http://qt-project.org/). Optional for the CalcQt example. +* [Qt 5](http://qt-project.org/). Optional for the CalcQt example. This header-only library is included in the source code: diff --git a/examples/CalcQt/CMakeLists.txt b/examples/CalcQt/CMakeLists.txt index 5caa4441..a8236a50 100644 --- a/examples/CalcQt/CMakeLists.txt +++ b/examples/CalcQt/CMakeLists.txt @@ -1,21 +1,49 @@ +cmake_minimum_required(VERSION 2.8.11) + project(CalcQt) -find_package(Qt4 COMPONENTS QtCore QtGui QtTest) +# Find the Core library +find_package(Qt5Core REQUIRED) +# Find the QtWidgets library +find_package(Qt5Widgets REQUIRED) +# Find the QtTest library +find_package(Qt5Test REQUIRED) + +set (QT5_FOUND ${Qt5Core_FOUND} AND ${Qt5Test_FOUND} AND ${Qt5Widgets_FOUND}) + +if(NOT QT5_FOUND) + message(WARNING "Qt5 not found") +endif() + +if(QT5_FOUND) + message(STATUS "Using Qt version ${Qt5Core_VERSION_STRING} ") -if(QT4_FOUND) - include(${QT_USE_FILE}) + # Find includes in corresponding build directories + set(CMAKE_INCLUDE_CURRENT_DIR ON) + # Instruct CMake to run moc automatically when needed. + set(CMAKE_AUTOMOC ON) + set(CALCQT_HEADERS src/CalculatorWidget.h) - qt4_wrap_cpp(CALCQT_HEADERS_MOC ${CALCQT_HEADERS}) - include_directories(${CUKE_INCLUDE_DIRS} src) - add_library(CalcQt src/CalculatorWidget ${CALCQT_HEADERS_MOC}) + set(CALCQT_SOURCES src/CalcQt.cpp src/CalculatorWidget.cpp) + set(QT_LIBRARIES Qt5::Core Qt5::Widgets Qt5::Test) + add_library(libcalcqt src/CalculatorWidget.cpp ${CALCQT_HEADERS}) + target_link_libraries(libcalcqt ${QT_LIBRARIES}) + + add_executable(calcqt ${CALCQT_SOURCES} ${CALCQT_HEADERS}) + target_link_libraries(calcqt libcalcqt ${QT_LIBRARIES}) + if(Boost_UNIT_TEST_FRAMEWORK_FOUND) - include_directories(${Boost_INCLUDE_DIRS}) - add_executable(BoostCalculatorQtSteps features/step_definitions/BoostCalculatorQtSteps) - target_link_libraries(BoostCalculatorQtSteps CalcQt ${Boost_UNIT_TEST_FRAMEWORK_LIBRARY} ${CUKE_LIBRARIES} ${QT_LIBRARIES}) + include_directories(${Boost_INCLUDE_DIRS} src/) + add_executable(BoostCalculatorQtSteps features/step_definitions/BoostCalculatorQtSteps ${CALCQT_HEADERS}) + target_link_libraries(BoostCalculatorQtSteps libcalcqt ${Boost_UNIT_TEST_FRAMEWORK_LIBRARY} ${CUKE_LIBRARIES} ${QT_LIBRARIES}) + endif() + + if(GTEST_FOUND) + include_directories(${GTEST_INCLUDE_DIRS} src/) + add_executable(GTestCalculatorQtSteps features/step_definitions/GTestCalculatorQtSteps) + target_link_libraries(GTestCalculatorQtSteps libcalcqt ${QT_LIBRARIES} ${GTEST_LIBRARIES} ${CUKE_LIBRARIES}) endif() - set(CALCQT_SOURCES src/CalcQt.cpp src/CalculatorWidget.cpp) - add_executable(calcqt ${CALCQT_SOURCES} ${CALCQT_HEADERS_MOC}) - target_link_libraries(calcqt ${QT_LIBRARIES}) endif() + diff --git a/examples/CalcQt/features/step_definitions/BoostCalculatorQtSteps.cpp b/examples/CalcQt/features/step_definitions/BoostCalculatorQtSteps.cpp index df7d9a29..56705ce7 100644 --- a/examples/CalcQt/features/step_definitions/BoostCalculatorQtSteps.cpp +++ b/examples/CalcQt/features/step_definitions/BoostCalculatorQtSteps.cpp @@ -7,7 +7,7 @@ #include #include -#include +#include "CalculatorWidget.h" static int argc = 0; static QApplication app(argc, 0); @@ -23,13 +23,13 @@ int millisecondsToWait() { } std::istream& operator>> (std::istream& in, QString& val) { std::string s; in >> s; val = s.c_str(); return in; } -std::ostream& operator<< (std::ostream& out, const QString& val) { out << val.toAscii().data(); return out; } +std::ostream& operator<< (std::ostream& out, const QString& val) { out << val.toLatin1().data(); return out; } GIVEN("^I just turned on the calculator$") { cucumber::ScenarioScope calculator; calculator->move(0, 0); calculator->show(); - QTest::qWaitForWindowShown(calculator.get()); + QTest::qWaitForWindowExposed(calculator.get()); QTest::qWait(millisecondsToWait()); } diff --git a/examples/CalcQt/features/step_definitions/GTestCalculatorQtSteps.cpp b/examples/CalcQt/features/step_definitions/GTestCalculatorQtSteps.cpp new file mode 100644 index 00000000..dc99d274 --- /dev/null +++ b/examples/CalcQt/features/step_definitions/GTestCalculatorQtSteps.cpp @@ -0,0 +1,73 @@ + +#include + +#include +#include + +#include +#include + +#include "CalculatorWidget.h" + +static int argc = 0; +static QApplication app(argc, 0); +static int milliseconds = -1; + +int millisecondsToWait() { + if (milliseconds < 0) + { + char* envVariable = getenv("CALCQT_STEP_DELAY"); + milliseconds = (0 != envVariable) ? atoi(envVariable) : 0; + } + return milliseconds; +} + +std::istream& operator>> (std::istream& in, QString& val) { std::string s; in >> s; val = s.c_str(); return in; } +std::ostream& operator<< (std::ostream& out, const QString& val) { out << val.toLatin1().data(); return out; } + +GIVEN("^I just turned on the calculator$") { + cucumber::ScenarioScope calculator; + calculator->move(0, 0); + calculator->show(); + QTest::qWaitForWindowExposed(calculator.get()); + QTest::qWait(millisecondsToWait()); +} + +WHEN("^I press (\\d+)$") { + REGEX_PARAM(unsigned int, n); + cucumber::ScenarioScope calculator; + QTest::keyClick(calculator.get(), Qt::Key_0 + n, Qt::NoModifier, millisecondsToWait()); +} + +WHEN("^I press add") { + cucumber::ScenarioScope calculator; + QTest::keyClick(calculator.get(), Qt::Key_Plus, Qt::NoModifier, millisecondsToWait()); +} + +WHEN("^I press calculate") { + cucumber::ScenarioScope calculator; + QTest::keyClick(calculator.get(), Qt::Key_Return, Qt::NoModifier, millisecondsToWait()); +} + +WHEN("^I press clear") { + cucumber::ScenarioScope calculator; + QTest::keyClick(calculator.get(), Qt::Key_Escape, Qt::NoModifier, millisecondsToWait()); +} + +WHEN("^I press subtract") { + cucumber::ScenarioScope calculator; + QTest::keyClick(calculator.get(), Qt::Key_Minus, Qt::NoModifier, millisecondsToWait()); +} + +THEN("^the display should be empty$") { + cucumber::ScenarioScope calculator; + EXPECT_EQ(calculator->display().size(), 0); + QTest::qWait(millisecondsToWait()); +} + +THEN("^the display should show (.*)$") { + REGEX_PARAM(QString, expected); + cucumber::ScenarioScope calculator; + EXPECT_EQ(expected, calculator->display()); + QTest::qWait(millisecondsToWait()); +} diff --git a/examples/CalcQt/src/CalculatorWidget.cpp b/examples/CalcQt/src/CalculatorWidget.cpp index 01505727..256edfa0 100644 --- a/examples/CalcQt/src/CalculatorWidget.cpp +++ b/examples/CalcQt/src/CalculatorWidget.cpp @@ -1,6 +1,5 @@ #include "CalculatorWidget.h" -#include #include #include #include @@ -8,7 +7,7 @@ #include CalculatorWidget::CalculatorWidget(QWidget *parent, Qt::WindowFlags flags) : QWidget(parent, flags) { - QGridLayout *layout = new QGridLayout; + QGridLayout *layout = new QGridLayout(this); layout->setSizeConstraint(QLayout::SetFixedSize); setLayout(layout); @@ -69,7 +68,7 @@ int CalculatorWidget::calculate(const QString& expression) { } pos += regexp.matchedLength(); if (pos < expression.length()) { - operation = expression.at(pos).toAscii(); + operation = expression.at(pos).toLatin1(); } } return result; @@ -103,6 +102,7 @@ void CalculatorWidget::keyPressEvent(QKeyEvent *event) { } void CalculatorWidget::keyReleaseEvent(QKeyEvent *event) { + Q_UNUSED(event) if (0 != keyclickedButton) { keyclickedButton->setDown(false); keyclickedButton = 0; diff --git a/examples/CalcQt/src/CalculatorWidget.h b/examples/CalcQt/src/CalculatorWidget.h index fe555cea..0f88bdce 100644 --- a/examples/CalcQt/src/CalculatorWidget.h +++ b/examples/CalcQt/src/CalculatorWidget.h @@ -1,7 +1,8 @@ class QLabel; class QPushButton; -#include class QSignalMapper; + +#include #include class CalculatorWidget : public QWidget {