From 47c733bb909eb80a74a4fed3a3249a3a7e98e8c9 Mon Sep 17 00:00:00 2001 From: Ronan Abhamon Date: Fri, 21 Oct 2016 16:13:51 +0200 Subject: [PATCH] feat(InvertedMouseArea): add spec file to test emitted signals --- tests/tools/test_qml | 7 +- tests/ui/modules/Common/Form/ListForm.qml | 1 - tests/ui/modules/Common/InvertedMouseArea.qml | 9 +- .../modules/Common/InvertedMouseArea.spec.qml | 84 +++++++++++++++++++ tests/ui/modules/Common/SearchBox.qml | 4 +- tests/ui/scripts/Utils/utils.js | 46 ++++++++-- tests/ui/scripts/Utils/utils.spec.qml | 63 ++++++++++++-- 7 files changed, 189 insertions(+), 25 deletions(-) create mode 100644 tests/ui/modules/Common/InvertedMouseArea.spec.qml diff --git a/tests/tools/test_qml b/tests/tools/test_qml index 1d8efab18..c26134f0f 100644 --- a/tests/tools/test_qml +++ b/tests/tools/test_qml @@ -4,10 +4,13 @@ # Tool to run unit tests on all `*.spec.qml` files. # ==================================================================== -RESOURCES_FILE='resources.qrc' TEST_RUNNER='qmltestrunner-qt5' + +RESOURCES_FILE='resources.qrc' TEST_FILE_EXTENSION='spec.qml' + MODULES_PATH='./ui/modules' +SCRIPTS_PATH='./ui/scripts' RED='\e[1;31m' GREEN='\e[1;32m' @@ -43,7 +46,7 @@ do if [ -f $spec_qml_file ]; then printf "${BLUE}Running unit qml tests of '${qml_file}'...${NC}\n" - $TEST_RUNNER -import $MODULES_PATH -input "$spec_qml_file" + $TEST_RUNNER -import $MODULES_PATH -import $SCRIPTS_PATH -input "$spec_qml_file" if [[ $? == 0 ]]; then printf "${GREEN}All unit tests have succeeded for '${spec_qml_file}'.\n" diff --git a/tests/ui/modules/Common/Form/ListForm.qml b/tests/ui/modules/Common/Form/ListForm.qml index d45da1f77..d33c9cd9e 100644 --- a/tests/ui/modules/Common/Form/ListForm.qml +++ b/tests/ui/modules/Common/Form/ListForm.qml @@ -122,7 +122,6 @@ RowLayout { InvertedMouseArea { enabled: textEdit.activeFocus height: textEdit.height - parent: parent width: textEdit.width onPressed: textEdit.focus = false diff --git a/tests/ui/modules/Common/InvertedMouseArea.qml b/tests/ui/modules/Common/InvertedMouseArea.qml index c1e2f5d1d..e89d625f3 100644 --- a/tests/ui/modules/Common/InvertedMouseArea.qml +++ b/tests/ui/modules/Common/InvertedMouseArea.qml @@ -41,8 +41,8 @@ Item { return ( point.x >= item.x && point.y >= item.y && - point.x <= item.x + item.width && - point.y <= item.y + item.height + point.x < item.x + item.width && + point.y < item.y + item.height ) } @@ -50,9 +50,8 @@ Item { // See: http://doc.qt.io/qt-5/qml-qtqml-component.html#completed-signal // // The creation order of components in a view is undefined, - // so the mouse area must be created only when `enabled === true`. - // - // In the first render, `enabled` must be equal to false. + // so the mouse area must be created only when the target component + // was completed. Component.onCompleted: enabled && _createMouseArea() Component.onDestruction: _deleteMouseArea() diff --git a/tests/ui/modules/Common/InvertedMouseArea.spec.qml b/tests/ui/modules/Common/InvertedMouseArea.spec.qml new file mode 100644 index 000000000..29f98d1f0 --- /dev/null +++ b/tests/ui/modules/Common/InvertedMouseArea.spec.qml @@ -0,0 +1,84 @@ +import QtQuick 2.7 +import QtTest 1.1 + +import Utils 1.0 + +// =================================================================== + +Rectangle { + id: root + + color: 'violet' + height: 200 + width: 300 + + Rectangle { + id: item + + color: 'pink' + height: 80 + width: 100 + x: 120 + y: 100 + + InvertedMouseArea { + id: invertedMouseArea + + anchors.fill: parent + } + } + + SignalSpy { + id: spy + + signalName: 'pressed' + } + + TestCase { + when: windowShown + + function test_randomInsideMouseArea () { + var failFun = function () { + fail('`pressed` signal was emitted.') + } + + invertedMouseArea.pressed.connect(failFun) + + Utils.times(100, function () { + var x = Math.floor(Utils.genRandomNumber(item.x, item.x + width)) + var y = Math.floor(Utils.genRandomNumber(item.y, item.y + height)) + + mouseClick(root, x, y) + }) + + wait(100) + invertedMouseArea.pressed.disconnect(failFun) + } + + function test_randomOutsideMouseArea () { + spy.target = invertedMouseArea + + Utils.times(50, function () { + var x = Math.floor(Utils.genRandomNumberBetweenIntervals([ + [ 0, item.x ], [ item.x + item.width, root.width ] + ])) + var y = Math.floor(Utils.genRandomNumberBetweenIntervals([ + [ 0, item.y ], [ item.y + item.height, root.height ] + ])) + + mouseClick(root, x, y) + spy.wait(100) + }) + + Utils.times(50, function () { + var x = Math.floor(Utils.genRandomNumber(item.x, item.x + item.width)) + var y = Math.floor(Utils.genRandomNumberBetweenIntervals([ + [ 0, item.y ], [ item.y + item.height, root.height ] + ])) + + mouseClick(root, x, y) + spy.wait(100) + }) + } + } +} diff --git a/tests/ui/modules/Common/SearchBox.qml b/tests/ui/modules/Common/SearchBox.qml index 89978e41b..c0b023f4e 100644 --- a/tests/ui/modules/Common/SearchBox.qml +++ b/tests/ui/modules/Common/SearchBox.qml @@ -79,10 +79,8 @@ Item { } InvertedMouseArea { + anchors.fill: parent enabled: menu.visible - height: parent.height - parent: parent - width: parent.width onPressed: _hideMenu() } diff --git a/tests/ui/scripts/Utils/utils.js b/tests/ui/scripts/Utils/utils.js index bb82c2469..81aa56bfe 100644 --- a/tests/ui/scripts/Utils/utils.js +++ b/tests/ui/scripts/Utils/utils.js @@ -30,15 +30,7 @@ function openWindow (window, parent, options) { object = component.createObject(parent) } - console.debug('Open window.') - - object.closing.connect(function () { - console.debug('Destroy window.') - object.destroy() - }) - object.exitStatus.connect(function (status) { - console.debug('Exit status: ' + status) - }) + object.closing.connect(object.destroy.bind(object)) if (options && options.exitHandler) { object.exitStatus.connect( @@ -135,3 +127,39 @@ function times (n, cb, context) { function isString (string) { return typeof string === 'string' || string instanceof String } + +// ------------------------------------------------------------------- + +// Generate a random number in the [min, max[ interval. +// Uniform distrib. +function genRandomNumber (min, max) { + return Math.random() * (max - min) + min +} + +// ------------------------------------------------------------------- + +// Generate a random number between a set of intervals. +// The `intervals` param must be orderer like this: +// `[ [ 1, 4 ], [ 8, 16 ], [ 22, 25 ] ]` +function genRandomNumberBetweenIntervals (intervals) { + // Compute the number of values. + var size = 0 + intervals.forEach(function (interval) { + size += interval[1] - interval[0] + }) + + // Generate a value in the interval: `[0, size[` + var n = genRandomNumber(0, size) + + // Map the value in the right interval. + n += intervals[0][0] + for (var i = 0; i < intervals.length - 1; i++) { + if (n < intervals[i][1]) { + break + } + + n += intervals[i + 1][0] - intervals[i][1] + } + + return n +} diff --git a/tests/ui/scripts/Utils/utils.spec.qml b/tests/ui/scripts/Utils/utils.spec.qml index 7fdada737..faffd6e16 100644 --- a/tests/ui/scripts/Utils/utils.spec.qml +++ b/tests/ui/scripts/Utils/utils.spec.qml @@ -99,11 +99,6 @@ TestCase { failed = true }) - // Simulate time - Utils.times(500000, function (i) { - // Nothing. - }) - if (failed) { fail('`setTimeout` callback was called before `wait`.') } @@ -160,4 +155,62 @@ TestCase { function test_isString (data) { compare(Utils.isString(data.input), data.output) } + + // ----------------------------------------------------------------- + + function test_genRandomNumber_data () { + return [ + { min: 42, max: 3600 }, + { min: 10, max: 100 }, + { min: 58, max: 61 }, + { min: 2, max: 3 } + ] + } + + function test_genRandomNumber (data) { + Utils.times(10, function () { + var n = Utils.genRandomNumber(data.min, data.max) + compare(n >= data.min && n < data.max, true) + }) + } + + function test_genRandomNumberId () { + compare(Utils.genRandomNumber(42, 42), 42) + } + + // ----------------------------------------------------------------- + + function test_genRandomNumberBetweenIntervals_data () { + return [ + { intervals: [ [ 1, 5 ] ] }, + { intervals: [ [ 8, 9 ], [ 10, 15 ] ] }, + { intervals: [ [ 1, 4 ], [ 8, 16 ], [ 22, 25 ] ] }, + { intervals: [ [ 11, 12 ], [ 50, 80 ], [ 92, 93 ], [ 1000, 1100 ] ] }, + { intervals: [ [ -5, -2 ] ] }, + { intervals: [ [ -5, -2 ], [ 12, 14 ] ] }, + { intervals: [ [ -127, -111 ], [ -35, -14 ], [ 1256, 1270 ], [ 10000, 10020 ] ] } + ] + } + + function test_genRandomNumberBetweenIntervals (data) { + var intervals = data.intervals + + Utils.times(10, function () { + var n = Utils.genRandomNumberBetweenIntervals(intervals) + + var soFarSoGood = false + for (var i = 0; i < intervals.length; i++) { + if (n >= intervals[i][0] && n < intervals[i][1]) { + soFarSoGood = true + break + } + } + + compare( + soFarSoGood, + true, + 'The generated number cannot be found in a interval.' + ) + }) + } }