From c3f03bbff1db14dc5b5436d8aef834512207d498 Mon Sep 17 00:00:00 2001 From: Ulf Hermann Date: Tue, 24 Nov 2015 16:17:27 +0100 Subject: Support multiple QML engines in V4 debugger Whenever the debugger is paused, there is exactly one engine that caused the debuggerPaused() slot to be called. We can only interact with that engine in any meaningful way. Of course you can shoot yourself in the foot with this tool. You can, for example, set a breakpoint that will be hit by multiple engines and then get confused about which engine just hit the breakpoint. Similar things are also possible with other kinds of debuggers, though. If this becomes a problem we can add an engine ID to the responses. Also, this does not fix the other debug services. So you might still not see the "correct" locals and expressions from the QQmlEngineDebugService while the debugger is not paused. Task-number: QTBUG-49615 Change-Id: Ie044f0aedb51481c4cf851635d7c12839251cbd0 Reviewed-by: Erik Verbruggen --- .../qqmldebugjs/data/breakpointRelocation.qml | 47 - .../debugger/qqmldebugjs/data/changeBreakpoint.qml | 52 - .../qml/debugger/qqmldebugjs/data/condition.qml | 46 - .../debugger/qqmldebugjs/data/createComponent.qml | 46 - .../qml/debugger/qqmldebugjs/data/exception.qml | 43 - .../qml/debugger/qqmldebugjs/data/loadjsfile.qml | 40 - .../qml/debugger/qqmldebugjs/data/oncompleted.qml | 45 - tests/auto/qml/debugger/qqmldebugjs/data/quit.qml | 45 - .../qml/debugger/qqmldebugjs/data/stepAction.qml | 49 - tests/auto/qml/debugger/qqmldebugjs/data/test.js | 45 - tests/auto/qml/debugger/qqmldebugjs/data/test.qml | 52 - tests/auto/qml/debugger/qqmldebugjs/data/timer.qml | 44 - .../auto/qml/debugger/qqmldebugjs/qqmldebugjs.pro | 25 +- .../qqmldebugjs/data/breakpointRelocation.qml | 47 + .../qqmldebugjs/data/changeBreakpoint.qml | 52 + .../qqmldebugjs/qqmldebugjs/data/condition.qml | 46 + .../qqmldebugjs/data/createComponent.qml | 46 + .../qqmldebugjs/qqmldebugjs/data/exception.qml | 43 + .../qqmldebugjs/qqmldebugjs/data/loadjsfile.qml | 40 + .../qqmldebugjs/qqmldebugjs/data/oncompleted.qml | 45 + .../debugger/qqmldebugjs/qqmldebugjs/data/quit.qml | 45 + .../qqmldebugjs/qqmldebugjs/data/stepAction.qml | 49 + .../debugger/qqmldebugjs/qqmldebugjs/data/test.js | 45 + .../debugger/qqmldebugjs/qqmldebugjs/data/test.qml | 52 + .../qqmldebugjs/qqmldebugjs/data/timer.qml | 44 + .../qqmldebugjs/qqmldebugjs/qqmldebugjs.pro | 24 + .../qqmldebugjs/qqmldebugjs/tst_qqmldebugjs.cpp | 1532 ++++++++++++++++++++ .../qqmldebugjsserver/qqmldebugjsserver.cpp | 48 + .../qqmldebugjsserver/qqmldebugjsserver.pro | 12 + .../qml/debugger/qqmldebugjs/tst_qqmldebugjs.cpp | 1467 ------------------- 30 files changed, 2173 insertions(+), 2043 deletions(-) delete mode 100644 tests/auto/qml/debugger/qqmldebugjs/data/breakpointRelocation.qml delete mode 100644 tests/auto/qml/debugger/qqmldebugjs/data/changeBreakpoint.qml delete mode 100644 tests/auto/qml/debugger/qqmldebugjs/data/condition.qml delete mode 100644 tests/auto/qml/debugger/qqmldebugjs/data/createComponent.qml delete mode 100644 tests/auto/qml/debugger/qqmldebugjs/data/exception.qml delete mode 100644 tests/auto/qml/debugger/qqmldebugjs/data/loadjsfile.qml delete mode 100644 tests/auto/qml/debugger/qqmldebugjs/data/oncompleted.qml delete mode 100644 tests/auto/qml/debugger/qqmldebugjs/data/quit.qml delete mode 100644 tests/auto/qml/debugger/qqmldebugjs/data/stepAction.qml delete mode 100644 tests/auto/qml/debugger/qqmldebugjs/data/test.js delete mode 100644 tests/auto/qml/debugger/qqmldebugjs/data/test.qml delete mode 100644 tests/auto/qml/debugger/qqmldebugjs/data/timer.qml create mode 100644 tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/data/breakpointRelocation.qml create mode 100644 tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/data/changeBreakpoint.qml create mode 100644 tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/data/condition.qml create mode 100644 tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/data/createComponent.qml create mode 100644 tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/data/exception.qml create mode 100644 tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/data/loadjsfile.qml create mode 100644 tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/data/oncompleted.qml create mode 100644 tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/data/quit.qml create mode 100644 tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/data/stepAction.qml create mode 100644 tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/data/test.js create mode 100644 tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/data/test.qml create mode 100644 tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/data/timer.qml create mode 100644 tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/qqmldebugjs.pro create mode 100644 tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/tst_qqmldebugjs.cpp create mode 100644 tests/auto/qml/debugger/qqmldebugjs/qqmldebugjsserver/qqmldebugjsserver.cpp create mode 100644 tests/auto/qml/debugger/qqmldebugjs/qqmldebugjsserver/qqmldebugjsserver.pro delete mode 100644 tests/auto/qml/debugger/qqmldebugjs/tst_qqmldebugjs.cpp (limited to 'tests/auto/qml/debugger') diff --git a/tests/auto/qml/debugger/qqmldebugjs/data/breakpointRelocation.qml b/tests/auto/qml/debugger/qqmldebugjs/data/breakpointRelocation.qml deleted file mode 100644 index 55663b7983..0000000000 --- a/tests/auto/qml/debugger/qqmldebugjs/data/breakpointRelocation.qml +++ /dev/null @@ -1,47 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL21$ -** 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 -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** As a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -import QtQuick 2.0 - -//DO NOT CHANGE - -Item { - Component.onCompleted: { - //Comment - - var x = 6; - } - - width : height + 2 -} - diff --git a/tests/auto/qml/debugger/qqmldebugjs/data/changeBreakpoint.qml b/tests/auto/qml/debugger/qqmldebugjs/data/changeBreakpoint.qml deleted file mode 100644 index 1bd9191334..0000000000 --- a/tests/auto/qml/debugger/qqmldebugjs/data/changeBreakpoint.qml +++ /dev/null @@ -1,52 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL21$ -** 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 -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** As a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -import QtQuick 2.0 - -//DO NOT CHANGE - -Item { - id: item - property int d: 0 - - function doSomething() { - var a = 5; - var b = 6; - } - - Timer { - id: timer; interval: 1; running: true; repeat: true - onTriggered: doSomething(); - } - -} diff --git a/tests/auto/qml/debugger/qqmldebugjs/data/condition.qml b/tests/auto/qml/debugger/qqmldebugjs/data/condition.qml deleted file mode 100644 index 2f9b3aceb2..0000000000 --- a/tests/auto/qml/debugger/qqmldebugjs/data/condition.qml +++ /dev/null @@ -1,46 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL21$ -** 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 -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** As a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -import QtQuick 2.0 - -//DO NOT CHANGE - -Item { - id: item - property int a: 0 - Timer { - id: timer; interval: 1; repeat: true; running: true - onTriggered: a++ - } -} - diff --git a/tests/auto/qml/debugger/qqmldebugjs/data/createComponent.qml b/tests/auto/qml/debugger/qqmldebugjs/data/createComponent.qml deleted file mode 100644 index 53b1f52745..0000000000 --- a/tests/auto/qml/debugger/qqmldebugjs/data/createComponent.qml +++ /dev/null @@ -1,46 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL21$ -** 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 -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** As a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -import QtQuick 2.0 - -//DO NOT CHANGE -Item { - Component.onCompleted: { - var component = Qt.createComponent("oncompleted.qml") - if (component.status === Component.Ready) { - component.createObject(); - } - } -} - - diff --git a/tests/auto/qml/debugger/qqmldebugjs/data/exception.qml b/tests/auto/qml/debugger/qqmldebugjs/data/exception.qml deleted file mode 100644 index d0fa4e715c..0000000000 --- a/tests/auto/qml/debugger/qqmldebugjs/data/exception.qml +++ /dev/null @@ -1,43 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL21$ -** 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 -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** As a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -import QtQuick 2.0 - -//DO NOT CHANGE - -Item { - id: root - - Component.onCompleted: dummy() -} - diff --git a/tests/auto/qml/debugger/qqmldebugjs/data/loadjsfile.qml b/tests/auto/qml/debugger/qqmldebugjs/data/loadjsfile.qml deleted file mode 100644 index 9fc75d251f..0000000000 --- a/tests/auto/qml/debugger/qqmldebugjs/data/loadjsfile.qml +++ /dev/null @@ -1,40 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL21$ -** 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 -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** As a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -import QtQuick 2.0 -import "test.js" as Script - -//DO NOT CHANGE -Item { - Component.onCompleted: Script.printMessage("onCompleted"); -} diff --git a/tests/auto/qml/debugger/qqmldebugjs/data/oncompleted.qml b/tests/auto/qml/debugger/qqmldebugjs/data/oncompleted.qml deleted file mode 100644 index 6f32af39ad..0000000000 --- a/tests/auto/qml/debugger/qqmldebugjs/data/oncompleted.qml +++ /dev/null @@ -1,45 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL21$ -** 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 -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** As a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -import QtQuick 2.0 - -//DO NOT CHANGE - -Item { - Component.onCompleted: { - console.log("Hello world") - } - id: root - property int a: 10 -} - diff --git a/tests/auto/qml/debugger/qqmldebugjs/data/quit.qml b/tests/auto/qml/debugger/qqmldebugjs/data/quit.qml deleted file mode 100644 index b858fdf942..0000000000 --- a/tests/auto/qml/debugger/qqmldebugjs/data/quit.qml +++ /dev/null @@ -1,45 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL21$ -** 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 -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** As a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -import QtQuick 2.0 - -//DO NOT CHANGE - -Item { - Timer { - running: true - triggeredOnStart: true - onTriggered: Qt.quit(); - } -} - diff --git a/tests/auto/qml/debugger/qqmldebugjs/data/stepAction.qml b/tests/auto/qml/debugger/qqmldebugjs/data/stepAction.qml deleted file mode 100644 index b9ee1380aa..0000000000 --- a/tests/auto/qml/debugger/qqmldebugjs/data/stepAction.qml +++ /dev/null @@ -1,49 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL21$ -** 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 -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** As a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -import QtQuick 2.0 - -//DO NOT CHANGE - -Item { - id: item - property int d: 0 - - function doSomething() { - var a = 5; - var b = 6; - } - - Component.onCompleted: doSomething() - -} diff --git a/tests/auto/qml/debugger/qqmldebugjs/data/test.js b/tests/auto/qml/debugger/qqmldebugjs/data/test.js deleted file mode 100644 index ca25e9baf7..0000000000 --- a/tests/auto/qml/debugger/qqmldebugjs/data/test.js +++ /dev/null @@ -1,45 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL21$ -** 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 -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** As a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -function printMessage(msg) -{ - print(msg); -} - -function add(a,b) -{ - //This is a comment and below is an empty line - - var out = a + b; - return out; -} diff --git a/tests/auto/qml/debugger/qqmldebugjs/data/test.qml b/tests/auto/qml/debugger/qqmldebugjs/data/test.qml deleted file mode 100644 index 5a7fa718f2..0000000000 --- a/tests/auto/qml/debugger/qqmldebugjs/data/test.qml +++ /dev/null @@ -1,52 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL21$ -** 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 -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** As a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -import QtQuick 2.0 - -//DO NOT CHANGE - -Item { - Component.onCompleted: { - var a = [1, 2] - var b = {a: "hello", d: 1 } - var c - var d = 12 - } - function foo() { - var a = [1, 2] - var b = {a: "hello", d: 1 } - var c - var d = 12 - } -} - diff --git a/tests/auto/qml/debugger/qqmldebugjs/data/timer.qml b/tests/auto/qml/debugger/qqmldebugjs/data/timer.qml deleted file mode 100644 index 1fee24a1fa..0000000000 --- a/tests/auto/qml/debugger/qqmldebugjs/data/timer.qml +++ /dev/null @@ -1,44 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL21$ -** 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 -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** As a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -import QtQuick 2.0 - -//DO NOT CHANGE -Item { - Timer { - id: timer; interval: 1; running: true; repeat: true; triggeredOnStart: true - onTriggered: { - console.log("timer"); - } - } -} diff --git a/tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs.pro b/tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs.pro index 4b3e204dd8..bd6debcea1 100644 --- a/tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs.pro +++ b/tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs.pro @@ -1,23 +1,4 @@ -CONFIG += testcase -TARGET = tst_qqmldebugjs -QT += qml testlib gui-private core-private -osx:CONFIG -= app_bundle +TEMPLATE = subdirs +SUBDIRS = qqmldebugjs qqmldebugjsserver -SOURCES += tst_qqmldebugjs.cpp - -INCLUDEPATH += ../shared -include(../../../shared/util.pri) -include(../shared/debugutil.pri) - -TESTDATA = data/* - -OTHER_FILES += data/test.qml data/test.js \ - data/timer.qml \ - data/exception.qml \ - data/oncompleted.qml \ - data/loadjsfile.qml \ - data/condition.qml \ - data/changeBreakpoint.qml \ - data/stepAction.qml \ - data/breakpointRelocation.qml \ - data/createComponent.qml +qqmldebugjs.depends = qqmldebugjsserver diff --git a/tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/data/breakpointRelocation.qml b/tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/data/breakpointRelocation.qml new file mode 100644 index 0000000000..55663b7983 --- /dev/null +++ b/tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/data/breakpointRelocation.qml @@ -0,0 +1,47 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL21$ +** 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 +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.0 + +//DO NOT CHANGE + +Item { + Component.onCompleted: { + //Comment + + var x = 6; + } + + width : height + 2 +} + diff --git a/tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/data/changeBreakpoint.qml b/tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/data/changeBreakpoint.qml new file mode 100644 index 0000000000..1bd9191334 --- /dev/null +++ b/tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/data/changeBreakpoint.qml @@ -0,0 +1,52 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL21$ +** 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 +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.0 + +//DO NOT CHANGE + +Item { + id: item + property int d: 0 + + function doSomething() { + var a = 5; + var b = 6; + } + + Timer { + id: timer; interval: 1; running: true; repeat: true + onTriggered: doSomething(); + } + +} diff --git a/tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/data/condition.qml b/tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/data/condition.qml new file mode 100644 index 0000000000..2f9b3aceb2 --- /dev/null +++ b/tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/data/condition.qml @@ -0,0 +1,46 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL21$ +** 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 +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.0 + +//DO NOT CHANGE + +Item { + id: item + property int a: 0 + Timer { + id: timer; interval: 1; repeat: true; running: true + onTriggered: a++ + } +} + diff --git a/tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/data/createComponent.qml b/tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/data/createComponent.qml new file mode 100644 index 0000000000..53b1f52745 --- /dev/null +++ b/tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/data/createComponent.qml @@ -0,0 +1,46 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL21$ +** 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 +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.0 + +//DO NOT CHANGE +Item { + Component.onCompleted: { + var component = Qt.createComponent("oncompleted.qml") + if (component.status === Component.Ready) { + component.createObject(); + } + } +} + + diff --git a/tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/data/exception.qml b/tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/data/exception.qml new file mode 100644 index 0000000000..d0fa4e715c --- /dev/null +++ b/tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/data/exception.qml @@ -0,0 +1,43 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL21$ +** 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 +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.0 + +//DO NOT CHANGE + +Item { + id: root + + Component.onCompleted: dummy() +} + diff --git a/tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/data/loadjsfile.qml b/tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/data/loadjsfile.qml new file mode 100644 index 0000000000..9fc75d251f --- /dev/null +++ b/tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/data/loadjsfile.qml @@ -0,0 +1,40 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL21$ +** 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 +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.0 +import "test.js" as Script + +//DO NOT CHANGE +Item { + Component.onCompleted: Script.printMessage("onCompleted"); +} diff --git a/tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/data/oncompleted.qml b/tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/data/oncompleted.qml new file mode 100644 index 0000000000..6f32af39ad --- /dev/null +++ b/tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/data/oncompleted.qml @@ -0,0 +1,45 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL21$ +** 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 +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.0 + +//DO NOT CHANGE + +Item { + Component.onCompleted: { + console.log("Hello world") + } + id: root + property int a: 10 +} + diff --git a/tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/data/quit.qml b/tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/data/quit.qml new file mode 100644 index 0000000000..b858fdf942 --- /dev/null +++ b/tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/data/quit.qml @@ -0,0 +1,45 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL21$ +** 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 +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.0 + +//DO NOT CHANGE + +Item { + Timer { + running: true + triggeredOnStart: true + onTriggered: Qt.quit(); + } +} + diff --git a/tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/data/stepAction.qml b/tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/data/stepAction.qml new file mode 100644 index 0000000000..b9ee1380aa --- /dev/null +++ b/tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/data/stepAction.qml @@ -0,0 +1,49 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL21$ +** 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 +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.0 + +//DO NOT CHANGE + +Item { + id: item + property int d: 0 + + function doSomething() { + var a = 5; + var b = 6; + } + + Component.onCompleted: doSomething() + +} diff --git a/tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/data/test.js b/tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/data/test.js new file mode 100644 index 0000000000..ca25e9baf7 --- /dev/null +++ b/tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/data/test.js @@ -0,0 +1,45 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL21$ +** 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 +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +function printMessage(msg) +{ + print(msg); +} + +function add(a,b) +{ + //This is a comment and below is an empty line + + var out = a + b; + return out; +} diff --git a/tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/data/test.qml b/tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/data/test.qml new file mode 100644 index 0000000000..5a7fa718f2 --- /dev/null +++ b/tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/data/test.qml @@ -0,0 +1,52 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL21$ +** 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 +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.0 + +//DO NOT CHANGE + +Item { + Component.onCompleted: { + var a = [1, 2] + var b = {a: "hello", d: 1 } + var c + var d = 12 + } + function foo() { + var a = [1, 2] + var b = {a: "hello", d: 1 } + var c + var d = 12 + } +} + diff --git a/tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/data/timer.qml b/tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/data/timer.qml new file mode 100644 index 0000000000..1fee24a1fa --- /dev/null +++ b/tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/data/timer.qml @@ -0,0 +1,44 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL21$ +** 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 +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +import QtQuick 2.0 + +//DO NOT CHANGE +Item { + Timer { + id: timer; interval: 1; running: true; repeat: true; triggeredOnStart: true + onTriggered: { + console.log("timer"); + } + } +} diff --git a/tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/qqmldebugjs.pro b/tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/qqmldebugjs.pro new file mode 100644 index 0000000000..79e772c1ee --- /dev/null +++ b/tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/qqmldebugjs.pro @@ -0,0 +1,24 @@ +CONFIG += testcase +TARGET = tst_qqmldebugjs +QT += qml testlib gui-private core-private +CONFIG -= debug_and_release_target +osx:CONFIG -= app_bundle + +SOURCES += tst_qqmldebugjs.cpp + +INCLUDEPATH += ../../shared +include(../../../../shared/util.pri) +include(../../shared/debugutil.pri) + +TESTDATA = data/* + +OTHER_FILES += data/test.qml data/test.js \ + data/timer.qml \ + data/exception.qml \ + data/oncompleted.qml \ + data/loadjsfile.qml \ + data/condition.qml \ + data/changeBreakpoint.qml \ + data/stepAction.qml \ + data/breakpointRelocation.qml \ + data/createComponent.qml diff --git a/tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/tst_qqmldebugjs.cpp b/tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/tst_qqmldebugjs.cpp new file mode 100644 index 0000000000..e0451466ef --- /dev/null +++ b/tests/auto/qml/debugger/qqmldebugjs/qqmldebugjs/tst_qqmldebugjs.cpp @@ -0,0 +1,1532 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL21$ +** 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 +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//QQmlDebugTest +#include "debugutil_p.h" +#include "../../../../shared/util.h" + +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#if defined (Q_OS_WINCE) +#undef IN +#undef OUT +#endif + +const char *V8REQUEST = "v8request"; +const char *V8MESSAGE = "v8message"; +const char *SEQ = "seq"; +const char *TYPE = "type"; +const char *COMMAND = "command"; +const char *ARGUMENTS = "arguments"; +const char *STEPACTION = "stepaction"; +const char *STEPCOUNT = "stepcount"; +const char *EXPRESSION = "expression"; +const char *FRAME = "frame"; +const char *GLOBAL = "global"; +const char *DISABLEBREAK = "disable_break"; +const char *HANDLES = "handles"; +const char *INCLUDESOURCE = "includeSource"; +const char *FROMFRAME = "fromFrame"; +const char *TOFRAME = "toFrame"; +const char *BOTTOM = "bottom"; +const char *NUMBER = "number"; +const char *FRAMENUMBER = "frameNumber"; +const char *TYPES = "types"; +const char *IDS = "ids"; +const char *FILTER = "filter"; +const char *FROMLINE = "fromLine"; +const char *TOLINE = "toLine"; +const char *TARGET = "target"; +const char *LINE = "line"; +const char *COLUMN = "column"; +const char *ENABLED = "enabled"; +const char *CONDITION = "condition"; +const char *IGNORECOUNT = "ignoreCount"; +const char *BREAKPOINT = "breakpoint"; +const char *FLAGS = "flags"; + +const char *CONTINEDEBUGGING = "continue"; +const char *EVALUATE = "evaluate"; +const char *LOOKUP = "lookup"; +const char *BACKTRACE = "backtrace"; +const char *SCOPE = "scope"; +const char *SCOPES = "scopes"; +const char *SCRIPTS = "scripts"; +const char *SOURCE = "source"; +const char *SETBREAKPOINT = "setbreakpoint"; +const char *CLEARBREAKPOINT = "clearbreakpoint"; +const char *SETEXCEPTIONBREAK = "setexceptionbreak"; +const char *VERSION = "version"; +const char *DISCONNECT = "disconnect"; +const char *GARBAGECOLLECTOR = "gc"; +//const char *PROFILE = "profile"; + +const char *CONNECT = "connect"; +const char *INTERRUPT = "interrupt"; + +const char *REQUEST = "request"; +const char *IN = "in"; +const char *NEXT = "next"; +const char *OUT = "out"; + +const char *FUNCTION = "function"; +const char *SCRIPT = "script"; +const char *SCRIPTREGEXP = "scriptRegExp"; +const char *EVENT = "event"; + +const char *ALL = "all"; +const char *UNCAUGHT = "uncaught"; + +//const char *PAUSE = "pause"; +//const char *RESUME = "resume"; + +const char *BLOCKMODE = "-qmljsdebugger=port:3771,3800,block"; +const char *NORMALMODE = "-qmljsdebugger=port:3771,3800"; +const char *BLOCKRESTRICTEDMODE = "-qmljsdebugger=port:3771,3800,block,services:V8Debugger"; +const char *NORMALRESTRICTEDMODE = "-qmljsdebugger=port:3771,3800,services:V8Debugger"; +const char *TEST_QMLFILE = "test.qml"; +const char *TEST_JSFILE = "test.js"; +const char *TIMER_QMLFILE = "timer.qml"; +const char *LOADJSFILE_QMLFILE = "loadjsfile.qml"; +const char *EXCEPTION_QMLFILE = "exception.qml"; +const char *ONCOMPLETED_QMLFILE = "oncompleted.qml"; +const char *CREATECOMPONENT_QMLFILE = "createComponent.qml"; +const char *CONDITION_QMLFILE = "condition.qml"; +const char *QUIT_QMLFILE = "quit.qml"; +const char *CHANGEBREAKPOINT_QMLFILE = "changeBreakpoint.qml"; +const char *STEPACTION_QMLFILE = "stepAction.qml"; +const char *BREAKPOINTRELOCATION_QMLFILE = "breakpointRelocation.qml"; + +#define VARIANTMAPINIT \ + QString obj("{}"); \ + QJSValue jsonVal = parser.call(QJSValueList() << obj); \ + jsonVal.setProperty(SEQ,QJSValue(seq++)); \ + jsonVal.setProperty(TYPE,REQUEST); + + +#undef QVERIFY +#define QVERIFY(statement) \ +do {\ + if (!QTest::qVerify((statement), #statement, "", __FILE__, __LINE__)) {\ + if (QTest::currentTestFailed()) \ + qDebug().nospace() << "\nDEBUGGEE OUTPUT:\n" << process->output();\ + return;\ + }\ +} while (0) + + +class QJSDebugClient; + +class tst_QQmlDebugJS : public QQmlDataTest +{ + Q_OBJECT + + void init(bool qmlscene, const QString &qmlFile = QString(TEST_QMLFILE), bool blockMode = true, + bool restrictServices = false); + +private slots: + void initTestCase(); + void cleanupTestCase(); + + void cleanup(); + + void connect_data(); + void connect(); + void interrupt_data() { targetData(); } + void interrupt(); + void getVersion_data() { targetData(); } + void getVersion(); +// void getVersionWhenAttaching(); + + void disconnect_data() { targetData(); } + void disconnect(); + + void setBreakpointInScriptOnCompleted_data() { targetData(); } + void setBreakpointInScriptOnCompleted(); + void setBreakpointInScriptOnComponentCreated_data() { targetData(); } + void setBreakpointInScriptOnComponentCreated(); + void setBreakpointInScriptOnTimerCallback_data() { targetData(); } + void setBreakpointInScriptOnTimerCallback(); + void setBreakpointInScriptInDifferentFile_data() { targetData(); } + void setBreakpointInScriptInDifferentFile(); + void setBreakpointInScriptOnComment_data() { targetData(); } + void setBreakpointInScriptOnComment(); + void setBreakpointInScriptOnEmptyLine_data() { targetData(); } + void setBreakpointInScriptOnEmptyLine(); + void setBreakpointInScriptOnOptimizedBinding_data() { targetData(); } + void setBreakpointInScriptOnOptimizedBinding(); + void setBreakpointInScriptWithCondition_data() { targetData(); } + void setBreakpointInScriptWithCondition(); + void setBreakpointInScriptThatQuits_data() { targetData(); } + void setBreakpointInScriptThatQuits(); + //void setBreakpointInFunction(); //NOT SUPPORTED +// void setBreakpointOnEvent(); +// void setBreakpointWhenAttaching(); + + void clearBreakpoint_data() { targetData(); } + void clearBreakpoint(); + + void setExceptionBreak_data() { targetData(); } + void setExceptionBreak(); + + void stepNext_data() { targetData(); } + void stepNext(); + void stepIn_data() { targetData(); } + void stepIn(); + void stepOut_data() { targetData(); } + void stepOut(); + void continueDebugging_data() { targetData(); } + void continueDebugging(); + + void backtrace_data() { targetData(); } + void backtrace(); + + void getFrameDetails_data() { targetData(); } + void getFrameDetails(); + + void getScopeDetails_data() { targetData(); } + void getScopeDetails(); + +// void evaluateInGlobalScope(); // Not supported yet. +// void evaluateInLocalScope(); // Not supported yet. + + void getScripts_data() { targetData(); } + void getScripts(); + + // void profile(); //NOT SUPPORTED + + // void verifyQMLOptimizerDisabled(); + +private: + void targetData(); + + QQmlDebugProcess *process; + QJSDebugClient *client; + QQmlDebugConnection *connection; + QTime t; +}; + +class QJSDebugClient : public QQmlDebugClient +{ + Q_OBJECT +public: + enum StepAction + { + Continue, + In, + Out, + Next + }; + + enum Exception + { + All, + Uncaught + }; + +// enum ProfileCommand +// { +// Pause, +// Resume +// }; + + QJSDebugClient(QQmlDebugConnection *connection) + : QQmlDebugClient(QLatin1String("V8Debugger"), connection), + seq(0) + { + parser = jsEngine.evaluate(QLatin1String("JSON.parse")); + stringify = jsEngine.evaluate(QLatin1String("JSON.stringify")); + } + + void connect(); + void interrupt(); + + void continueDebugging(StepAction stepAction); + void evaluate(QString expr, bool global = false, bool disableBreak = false, int frame = -1, const QVariantMap &addContext = QVariantMap()); + void lookup(QList handles, bool includeSource = false); + void backtrace(int fromFrame = -1, int toFrame = -1, bool bottom = false); + void frame(int number = -1); + void scope(int number = -1, int frameNumber = -1); + void scripts(int types = 4, QList ids = QList(), bool includeSource = false, QVariant filter = QVariant()); + void setBreakpoint(QString type, QString target, int line = -1, int column = -1, bool enabled = true, QString condition = QString(), int ignoreCount = -1); + void clearBreakpoint(int breakpoint); + void setExceptionBreak(Exception type, bool enabled = false); + void version(); + //void profile(ProfileCommand command); //NOT SUPPORTED + void disconnect(); + +protected: + //inherited from QQmlDebugClient + void stateChanged(State state); + void messageReceived(const QByteArray &data); + +signals: + void enabled(); + void connected(); + void interruptRequested(); + void result(); + void stopped(); + void scriptsResult(); + void evaluateResult(); + +private: + void sendMessage(const QByteArray &); + void flushSendBuffer(); + QByteArray packMessage(const QByteArray &type, const QByteArray &message = QByteArray()); + +private: + QJSEngine jsEngine; + int seq; + + QList sendBuffer; +public: + QJSValue parser; + QJSValue stringify; + QByteArray response; + +}; + +void QJSDebugClient::connect() +{ + sendMessage(packMessage(CONNECT)); +} + +void QJSDebugClient::interrupt() +{ + sendMessage(packMessage(INTERRUPT)); +} + +void QJSDebugClient::continueDebugging(StepAction action) +{ + // { "seq" : , + // "type" : "request", + // "command" : "continue", + // "arguments" : { "stepaction" : <"in", "next" or "out">, + // "stepcount" : + // } + // } + VARIANTMAPINIT; + jsonVal.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(CONTINEDEBUGGING))); + + if (action != Continue) { + QJSValue args = parser.call(QJSValueList() << obj); + switch (action) { + case In: args.setProperty(QLatin1String(STEPACTION),QJSValue(QLatin1String(IN))); + break; + case Out: args.setProperty(QLatin1String(STEPACTION),QJSValue(QLatin1String(OUT))); + break; + case Next: args.setProperty(QLatin1String(STEPACTION),QJSValue(QLatin1String(NEXT))); + break; + default:break; + } + if (!args.isUndefined()) { + jsonVal.setProperty(QLatin1String(ARGUMENTS),args); + } + } + QJSValue json = stringify.call(QJSValueList() << jsonVal); + sendMessage(packMessage(V8REQUEST, json.toString().toUtf8())); +} + +void QJSDebugClient::evaluate(QString expr, bool global, bool disableBreak, int frame, const QVariantMap &/*addContext*/) +{ + // { "seq" : , + // "type" : "request", + // "command" : "evaluate", + // "arguments" : { "expression" : , + // "frame" : , + // "global" : , + // "disable_break" : , + // "additional_context" : [ + // { "name" : , "handle" : }, + // { "name" : , "handle" : }, + // ... + // ] + // } + // } + VARIANTMAPINIT; + jsonVal.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(EVALUATE))); + + QJSValue args = parser.call(QJSValueList() << obj); + args.setProperty(QLatin1String(EXPRESSION),QJSValue(expr)); + + if (frame != -1) + args.setProperty(QLatin1String(FRAME),QJSValue(frame)); + + if (global) + args.setProperty(QLatin1String(GLOBAL),QJSValue(global)); + + if (disableBreak) + args.setProperty(QLatin1String(DISABLEBREAK),QJSValue(disableBreak)); + + if (!args.isUndefined()) { + jsonVal.setProperty(QLatin1String(ARGUMENTS),args); + } + + QJSValue json = stringify.call(QJSValueList() << jsonVal); + sendMessage(packMessage(V8REQUEST, json.toString().toUtf8())); +} + +void QJSDebugClient::lookup(QList handles, bool includeSource) +{ + // { "seq" : , + // "type" : "request", + // "command" : "lookup", + // "arguments" : { "handles" : , + // "includeSource" : , + // } + // } + VARIANTMAPINIT; + jsonVal.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(LOOKUP))); + + QJSValue args = parser.call(QJSValueList() << obj); + + QString arr("[]"); + QJSValue array = parser.call(QJSValueList() << arr); + int index = 0; + foreach (int handle, handles) { + array.setProperty(index++,QJSValue(handle)); + } + args.setProperty(QLatin1String(HANDLES),array); + + if (includeSource) + args.setProperty(QLatin1String(INCLUDESOURCE),QJSValue(includeSource)); + + if (!args.isUndefined()) { + jsonVal.setProperty(QLatin1String(ARGUMENTS),args); + } + + QJSValue json = stringify.call(QJSValueList() << jsonVal); + sendMessage(packMessage(V8REQUEST, json.toString().toUtf8())); +} + +void QJSDebugClient::backtrace(int fromFrame, int toFrame, bool bottom) +{ + // { "seq" : , + // "type" : "request", + // "command" : "backtrace", + // "arguments" : { "fromFrame" : + // "toFrame" : + // "bottom" : + // } + // } + VARIANTMAPINIT; + jsonVal.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(BACKTRACE))); + + QJSValue args = parser.call(QJSValueList() << obj); + + if (fromFrame != -1) + args.setProperty(QLatin1String(FROMFRAME),QJSValue(fromFrame)); + + if (toFrame != -1) + args.setProperty(QLatin1String(TOFRAME),QJSValue(toFrame)); + + if (bottom) + args.setProperty(QLatin1String(BOTTOM),QJSValue(bottom)); + + if (!args.isUndefined()) { + jsonVal.setProperty(QLatin1String(ARGUMENTS),args); + } + + QJSValue json = stringify.call(QJSValueList() << jsonVal); + sendMessage(packMessage(V8REQUEST, json.toString().toUtf8())); +} + +void QJSDebugClient::frame(int number) +{ + // { "seq" : , + // "type" : "request", + // "command" : "frame", + // "arguments" : { "number" : + // } + // } + VARIANTMAPINIT; + jsonVal.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(FRAME))); + + if (number != -1) { + QJSValue args = parser.call(QJSValueList() << obj); + args.setProperty(QLatin1String(NUMBER),QJSValue(number)); + + if (!args.isUndefined()) { + jsonVal.setProperty(QLatin1String(ARGUMENTS),args); + } + } + + QJSValue json = stringify.call(QJSValueList() << jsonVal); + sendMessage(packMessage(V8REQUEST, json.toString().toUtf8())); +} + +void QJSDebugClient::scope(int number, int frameNumber) +{ + // { "seq" : , + // "type" : "request", + // "command" : "scope", + // "arguments" : { "number" : + // "frameNumber" : + // } + // } + VARIANTMAPINIT; + jsonVal.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(SCOPE))); + + if (number != -1) { + QJSValue args = parser.call(QJSValueList() << obj); + args.setProperty(QLatin1String(NUMBER),QJSValue(number)); + + if (frameNumber != -1) + args.setProperty(QLatin1String(FRAMENUMBER),QJSValue(frameNumber)); + + if (!args.isUndefined()) { + jsonVal.setProperty(QLatin1String(ARGUMENTS),args); + } + } + + QJSValue json = stringify.call(QJSValueList() << jsonVal); + sendMessage(packMessage(V8REQUEST, json.toString().toUtf8())); +} + +void QJSDebugClient::scripts(int types, QList ids, bool includeSource, QVariant /*filter*/) +{ + // { "seq" : , + // "type" : "request", + // "command" : "scripts", + // "arguments" : { "types" : + // "ids" : + // "includeSource" : + // "filter" : + // } + // } + VARIANTMAPINIT; + jsonVal.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(SCRIPTS))); + + QJSValue args = parser.call(QJSValueList() << obj); + args.setProperty(QLatin1String(TYPES),QJSValue(types)); + + if (ids.count()) { + QString arr("[]"); + QJSValue array = parser.call(QJSValueList() << arr); + int index = 0; + foreach (int id, ids) { + array.setProperty(index++,QJSValue(id)); + } + args.setProperty(QLatin1String(IDS),array); + } + + if (includeSource) + args.setProperty(QLatin1String(INCLUDESOURCE),QJSValue(includeSource)); + + if (!args.isUndefined()) { + jsonVal.setProperty(QLatin1String(ARGUMENTS),args); + } + + QJSValue json = stringify.call(QJSValueList() << jsonVal); + sendMessage(packMessage(V8REQUEST, json.toString().toUtf8())); +} + +void QJSDebugClient::setBreakpoint(QString type, QString target, int line, int column, bool enabled, QString condition, int ignoreCount) +{ + // { "seq" : , + // "type" : "request", + // "command" : "setbreakpoint", + // "arguments" : { "type" : <"function" or "script" or "scriptId" or "scriptRegExp"> + // "target" : + // "line" : + // "column" : + // "enabled" : + // "condition" : + // "ignoreCount" : + // } + // } + + if (type == QLatin1String(EVENT)) { + QPacket rs(connection()->currentDataStreamVersion()); + rs << target.toUtf8() << enabled; + sendMessage(packMessage(QByteArray("breakonsignal"), rs.data())); + } else { + VARIANTMAPINIT; + jsonVal.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(SETBREAKPOINT))); + + QJSValue args = parser.call(QJSValueList() << obj); + + args.setProperty(QLatin1String(TYPE),QJSValue(type)); + args.setProperty(QLatin1String(TARGET),QJSValue(target)); + + if (line != -1) + args.setProperty(QLatin1String(LINE),QJSValue(line)); + + if (column != -1) + args.setProperty(QLatin1String(COLUMN),QJSValue(column)); + + args.setProperty(QLatin1String(ENABLED),QJSValue(enabled)); + + if (!condition.isEmpty()) + args.setProperty(QLatin1String(CONDITION),QJSValue(condition)); + + if (ignoreCount != -1) + args.setProperty(QLatin1String(IGNORECOUNT),QJSValue(ignoreCount)); + + if (!args.isUndefined()) { + jsonVal.setProperty(QLatin1String(ARGUMENTS),args); + } + + QJSValue json = stringify.call(QJSValueList() << jsonVal); + sendMessage(packMessage(V8REQUEST, json.toString().toUtf8())); + } +} + +void QJSDebugClient::clearBreakpoint(int breakpoint) +{ + // { "seq" : , + // "type" : "request", + // "command" : "clearbreakpoint", + // "arguments" : { "breakpoint" : + // } + // } + VARIANTMAPINIT; + jsonVal.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(CLEARBREAKPOINT))); + + QJSValue args = parser.call(QJSValueList() << obj); + + args.setProperty(QLatin1String(BREAKPOINT),QJSValue(breakpoint)); + + if (!args.isUndefined()) { + jsonVal.setProperty(QLatin1String(ARGUMENTS),args); + } + + QJSValue json = stringify.call(QJSValueList() << jsonVal); + sendMessage(packMessage(V8REQUEST, json.toString().toUtf8())); +} + +void QJSDebugClient::setExceptionBreak(Exception type, bool enabled) +{ + // { "seq" : , + // "type" : "request", + // "command" : "setexceptionbreak", + // "arguments" : { "type" : , + // "enabled" : + // } + // } + VARIANTMAPINIT; + jsonVal.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(SETEXCEPTIONBREAK))); + + QJSValue args = parser.call(QJSValueList() << obj); + + if (type == All) + args.setProperty(QLatin1String(TYPE),QJSValue(QLatin1String(ALL))); + else if (type == Uncaught) + args.setProperty(QLatin1String(TYPE),QJSValue(QLatin1String(UNCAUGHT))); + + if (enabled) + args.setProperty(QLatin1String(ENABLED),QJSValue(enabled)); + + if (!args.isUndefined()) { + jsonVal.setProperty(QLatin1String(ARGUMENTS),args); + } + + QJSValue json = stringify.call(QJSValueList() << jsonVal); + sendMessage(packMessage(V8REQUEST, json.toString().toUtf8())); +} + +void QJSDebugClient::version() +{ + // { "seq" : , + // "type" : "request", + // "command" : "version", + // } + VARIANTMAPINIT; + jsonVal.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(VERSION))); + + QJSValue json = stringify.call(QJSValueList() << jsonVal); + sendMessage(packMessage(V8REQUEST, json.toString().toUtf8())); +} + +//void QJSDebugClient::profile(ProfileCommand command) +//{ +//// { "seq" : , +//// "type" : "request", +//// "command" : "profile", +//// "arguments" : { "command" : "resume" or "pause" } +//// } +// VARIANTMAPINIT; +// jsonVal.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(PROFILE))); + +// QJSValue args = parser.call(QJSValueList() << obj); + +// if (command == Resume) +// args.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(RESUME))); +// else +// args.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(PAUSE))); + +// args.setProperty(QLatin1String("modules"),QJSValue(1)); +// if (!args.isUndefined()) { +// jsonVal.setProperty(QLatin1String(ARGUMENTS),args); +// } + +// QJSValue json = stringify.call(QJSValueList() << jsonVal); +// sendMessage(packMessage(V8REQUEST, json.toString().toUtf8())); +//} + +void QJSDebugClient::disconnect() +{ + // { "seq" : , + // "type" : "request", + // "command" : "disconnect", + // } + VARIANTMAPINIT; + jsonVal.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(DISCONNECT))); + + QJSValue json = stringify.call(QJSValueList() << jsonVal); + sendMessage(packMessage(DISCONNECT, json.toString().toUtf8())); +} + +void QJSDebugClient::stateChanged(State state) +{ + if (state == Enabled) { + flushSendBuffer(); + emit enabled(); + } +} + +void QJSDebugClient::messageReceived(const QByteArray &data) +{ + QPacket ds(connection()->currentDataStreamVersion(), data); + QByteArray command; + ds >> command; + + if (command == "V8DEBUG") { + QByteArray type; + ds >> type >> response; + + if (type == CONNECT) { + emit connected(); + + } else if (type == INTERRUPT) { + emit interruptRequested(); + + } else if (type == V8MESSAGE) { + QString jsonString(response); + QVariantMap value = parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap(); + QString type = value.value("type").toString(); + + if (type == "response") { + + if (!value.value("success").toBool()) { +// qDebug() << "Error: The test case will fail since no signal is emitted"; + return; + } + + QString debugCommand(value.value("command").toString()); + if (debugCommand == "backtrace" || + debugCommand == "lookup" || + debugCommand == "setbreakpoint" || + debugCommand == "evaluate" || + debugCommand == "version" || + debugCommand == "disconnect" || + debugCommand == "gc" || + debugCommand == "changebreakpoint" || + debugCommand == "clearbreakpoint" || + debugCommand == "frame" || + debugCommand == "scope" || + debugCommand == "scopes" || + debugCommand == "scripts" || + debugCommand == "source" || + debugCommand == "setexceptionbreak" /*|| + debugCommand == "profile"*/) { + emit result(); + + } else { + // DO NOTHING + } + //Emit separate signals for scripts ane evaluate + //as the associated test cases are flaky + if (debugCommand == "scripts") + emit scriptsResult(); + if (debugCommand == "evaluate") + emit evaluateResult(); + + } else if (type == QLatin1String(EVENT)) { + QString event(value.value(QLatin1String(EVENT)).toString()); + + if (event == "break" || + event == "exception") + emit stopped(); + } + + } + } +} + +void QJSDebugClient::sendMessage(const QByteArray &msg) +{ + if (state() == Enabled) { + QQmlDebugClient::sendMessage(msg); + } else { + sendBuffer.append(msg); + } +} + +void QJSDebugClient::flushSendBuffer() +{ + foreach (const QByteArray &msg, sendBuffer) + QQmlDebugClient::sendMessage(msg); + sendBuffer.clear(); +} + +QByteArray QJSDebugClient::packMessage(const QByteArray &type, const QByteArray &message) +{ + QPacket rs(connection()->currentDataStreamVersion()); + QByteArray cmd = "V8DEBUG"; + rs << cmd << type << message; + return rs.data(); +} + +void tst_QQmlDebugJS::initTestCase() +{ + QQmlDataTest::initTestCase(); + t.start(); + process = 0; + client = 0; + connection = 0; +} + +void tst_QQmlDebugJS::cleanupTestCase() +{ + if (process) { + process->stop(); + delete process; + } + + if (client) + delete client; + + if (connection) + delete connection; + +// qDebug() << "Time Elapsed:" << t.elapsed(); +} + +void tst_QQmlDebugJS::init(bool qmlscene, const QString &qmlFile, bool blockMode, + bool restrictServices) +{ + connection = new QQmlDebugConnection(); + if (qmlscene) + process = new QQmlDebugProcess(QLibraryInfo::location(QLibraryInfo::BinariesPath) + + "/qmlscene", this); + else + process = new QQmlDebugProcess(QCoreApplication::applicationDirPath() + + QLatin1String("/qqmldebugjsserver"), this); + client = new QJSDebugClient(connection); + QList others = QQmlDebugTest::createOtherClients(connection); + + const char *args = 0; + if (blockMode) + args = restrictServices ? BLOCKRESTRICTEDMODE : BLOCKMODE; + else + args = restrictServices ? NORMALRESTRICTEDMODE : NORMALMODE; + + process->start(QStringList() << QLatin1String(args) << testFile(qmlFile)); + + QVERIFY(process->waitForSessionStart()); + + const int port = process->debugPort(); + connection->connectToHost("127.0.0.1", port); + QVERIFY(connection->waitForConnected()); + + + if (client->state() != QQmlDebugClient::Enabled) + QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(enabled()))); + + foreach (QQmlDebugClient *otherClient, others) + QCOMPARE(otherClient->state(), restrictServices ? QQmlDebugClient::Unavailable : + QQmlDebugClient::Enabled); + qDeleteAll(others); +} + +void tst_QQmlDebugJS::cleanup() +{ + if (QTest::currentTestFailed()) { + qDebug() << "Process State:" << process->state(); + qDebug() << "Application Output:" << process->output(); + } + + if (process) { + process->stop(); + delete process; + } + + if (client) + delete client; + + if (connection) + delete connection; + + process = 0; + client = 0; + connection = 0; +} + +void tst_QQmlDebugJS::connect_data() +{ + QTest::addColumn("blockMode"); + QTest::addColumn("restrictMode"); + QTest::addColumn("qmlscene"); + QTest::newRow("normal / unrestricted / custom") << false << false << false; + QTest::newRow("block / unrestricted / custom") << true << false << false; + QTest::newRow("normal / restricted / custom") << false << true << false; + QTest::newRow("block / restricted / custom") << true << true << false; + QTest::newRow("normal / unrestricted / qmlscene") << false << false << true; + QTest::newRow("block / unrestricted / qmlscene") << true << false << true; + QTest::newRow("normal / restricted / qmlscene") << false << true << true; + QTest::newRow("block / restricted / qmlscene") << true << true << true; +} + +void tst_QQmlDebugJS::connect() +{ + QFETCH(bool, blockMode); + QFETCH(bool, restrictMode); + QFETCH(bool, qmlscene); + init(qmlscene, QString(TEST_QMLFILE), blockMode, restrictMode); + client->connect(); + QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(connected()))); +} + +void tst_QQmlDebugJS::interrupt() +{ + //void connect() + + QFETCH(bool, qmlscene); + init(qmlscene); + client->connect(); + + client->interrupt(); + QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(interruptRequested()))); +} + +void tst_QQmlDebugJS::getVersion() +{ + //void version() + + QFETCH(bool, qmlscene); + init(qmlscene); + client->connect(); + QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(connected()))); + + client->version(); + QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(result()))); +} + +/* TODO fails because of a race condition when starting up the engine before the view +void tst_QQmlDebugJS::getVersionWhenAttaching() +{ + //void version() + + QVERIFY(init(QLatin1String(TIMER_QMLFILE), false)); + client->connect(); + + client->version(); + QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(result()))); +} +*/ + +void tst_QQmlDebugJS::disconnect() +{ + //void disconnect() + + QFETCH(bool, qmlscene); + init(qmlscene); + client->connect(); + + client->disconnect(); + QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(result()))); +} + +void tst_QQmlDebugJS::setBreakpointInScriptOnCompleted() +{ + //void setBreakpoint(QString type, QString target, int line = -1, int column = -1, bool enabled = false, QString condition = QString(), int ignoreCount = -1) + QFETCH(bool, qmlscene); + + int sourceLine = 39; + init(qmlscene, ONCOMPLETED_QMLFILE); + + client->setBreakpoint(QLatin1String(SCRIPTREGEXP), QLatin1String(ONCOMPLETED_QMLFILE), sourceLine, -1, true); + client->connect(); + QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped()))); + + QString jsonString(client->response); + QVariantMap value = client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap(); + + QVariantMap body = value.value("body").toMap(); + + QCOMPARE(body.value("sourceLine").toInt(), sourceLine); + QCOMPARE(QFileInfo(body.value("script").toMap().value("name").toString()).fileName(), QLatin1String(ONCOMPLETED_QMLFILE)); +} + +void tst_QQmlDebugJS::setBreakpointInScriptOnComponentCreated() +{ + //void setBreakpoint(QString type, QString target, int line = -1, int column = -1, bool enabled = false, QString condition = QString(), int ignoreCount = -1) + QFETCH(bool, qmlscene); + + int sourceLine = 39; + init(qmlscene, CREATECOMPONENT_QMLFILE); + + client->setBreakpoint(QLatin1String(SCRIPTREGEXP), QLatin1String(ONCOMPLETED_QMLFILE), sourceLine, -1, true); + client->connect(); + QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped()))); + + QString jsonString(client->response); + QVariantMap value = client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap(); + + QVariantMap body = value.value("body").toMap(); + + QCOMPARE(body.value("sourceLine").toInt(), sourceLine); + QCOMPARE(QFileInfo(body.value("script").toMap().value("name").toString()).fileName(), QLatin1String(ONCOMPLETED_QMLFILE)); +} + +void tst_QQmlDebugJS::setBreakpointInScriptOnTimerCallback() +{ + QFETCH(bool, qmlscene); + int sourceLine = 40; + init(qmlscene, TIMER_QMLFILE); + + client->connect(); + //We can set the breakpoint after connect() here because the timer is repeating and if we miss + //its first iteration we can still catch the second one. + client->setBreakpoint(QLatin1String(SCRIPTREGEXP), QLatin1String(TIMER_QMLFILE), sourceLine, -1, true); + QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped()))); + + QString jsonString(client->response); + QVariantMap value = client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap(); + + QVariantMap body = value.value("body").toMap(); + + QCOMPARE(body.value("sourceLine").toInt(), sourceLine); + QCOMPARE(QFileInfo(body.value("script").toMap().value("name").toString()).fileName(), QLatin1String(TIMER_QMLFILE)); +} + +void tst_QQmlDebugJS::setBreakpointInScriptInDifferentFile() +{ + //void setBreakpoint(QString type, QString target, int line = -1, int column = -1, bool enabled = false, QString condition = QString(), int ignoreCount = -1) + QFETCH(bool, qmlscene); + + int sourceLine = 35; + init(qmlscene, LOADJSFILE_QMLFILE); + + client->setBreakpoint(QLatin1String(SCRIPTREGEXP), QLatin1String(TEST_JSFILE), sourceLine, -1, true); + client->connect(); + QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped()))); + + QString jsonString(client->response); + QVariantMap value = client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap(); + + QVariantMap body = value.value("body").toMap(); + + QCOMPARE(body.value("sourceLine").toInt(), sourceLine); + QCOMPARE(QFileInfo(body.value("script").toMap().value("name").toString()).fileName(), QLatin1String(TEST_JSFILE)); +} + +void tst_QQmlDebugJS::setBreakpointInScriptOnComment() +{ + //void setBreakpoint(QString type, QString target, int line = -1, int column = -1, bool enabled = false, QString condition = QString(), int ignoreCount = -1) + QFETCH(bool, qmlscene); + + int sourceLine = 39; + int actualLine = 41; + init(qmlscene, BREAKPOINTRELOCATION_QMLFILE); + + client->setBreakpoint(QLatin1String(SCRIPTREGEXP), QLatin1String(BREAKPOINTRELOCATION_QMLFILE), sourceLine, -1, true); + client->connect(); + QEXPECT_FAIL("", "Relocation of breakpoints is disabled right now", Abort); + QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped()), 1)); + + QString jsonString(client->response); + QVariantMap value = client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap(); + + QVariantMap body = value.value("body").toMap(); + + QCOMPARE(body.value("sourceLine").toInt(), actualLine); + QCOMPARE(QFileInfo(body.value("script").toMap().value("name").toString()).fileName(), QLatin1String(BREAKPOINTRELOCATION_QMLFILE)); +} + +void tst_QQmlDebugJS::setBreakpointInScriptOnEmptyLine() +{ + //void setBreakpoint(QString type, QString target, int line = -1, int column = -1, bool enabled = false, QString condition = QString(), int ignoreCount = -1) + QFETCH(bool, qmlscene); + + int sourceLine = 40; + int actualLine = 41; + init(qmlscene, BREAKPOINTRELOCATION_QMLFILE); + + client->setBreakpoint(QLatin1String(SCRIPTREGEXP), QLatin1String(BREAKPOINTRELOCATION_QMLFILE), sourceLine, -1, true); + client->connect(); + QEXPECT_FAIL("", "Relocation of breakpoints is disabled right now", Abort); + QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped()), 1)); + + QString jsonString(client->response); + QVariantMap value = client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap(); + + QVariantMap body = value.value("body").toMap(); + + QCOMPARE(body.value("sourceLine").toInt(), actualLine); + QCOMPARE(QFileInfo(body.value("script").toMap().value("name").toString()).fileName(), QLatin1String(BREAKPOINTRELOCATION_QMLFILE)); +} + +void tst_QQmlDebugJS::setBreakpointInScriptOnOptimizedBinding() +{ + //void setBreakpoint(QString type, QString target, int line = -1, int column = -1, bool enabled = false, QString condition = QString(), int ignoreCount = -1) + QFETCH(bool, qmlscene); + + int sourceLine = 44; + init(qmlscene, BREAKPOINTRELOCATION_QMLFILE); + + client->setBreakpoint(QLatin1String(SCRIPTREGEXP), QLatin1String(BREAKPOINTRELOCATION_QMLFILE), sourceLine, -1, true); + client->connect(); + QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped()))); + + QString jsonString(client->response); + QVariantMap value = client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap(); + + QVariantMap body = value.value("body").toMap(); + + QCOMPARE(body.value("sourceLine").toInt(), sourceLine); + QCOMPARE(QFileInfo(body.value("script").toMap().value("name").toString()).fileName(), QLatin1String(BREAKPOINTRELOCATION_QMLFILE)); +} + +void tst_QQmlDebugJS::setBreakpointInScriptWithCondition() +{ + QFETCH(bool, qmlscene); + int out = 10; + int sourceLine = 42; + init(qmlscene, CONDITION_QMLFILE); + + client->connect(); + //The breakpoint is in a timer loop so we can set it after connect(). + client->setBreakpoint(QLatin1String(SCRIPTREGEXP), QLatin1String(CONDITION_QMLFILE), sourceLine, 1, true, QLatin1String("a > 10")); + QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped()))); + + //Get the frame index + QString jsonString = client->response; + QVariantMap value = client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap(); + + { + QVariantMap body = value.value("body").toMap(); + int frameIndex = body.value("index").toInt(); + + //Verify the value of 'result' + client->evaluate(QLatin1String("a"),frameIndex); + QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(result()))); + } + + jsonString = client->response; + QJSValue val = client->parser.call(QJSValueList() << QJSValue(jsonString)); + QVERIFY(val.isObject()); + QJSValue body = val.property(QStringLiteral("body")); + QVERIFY(body.isObject()); + val = body.property("value"); + QVERIFY(val.isNumber()); + + const int a = val.toInt(); + QVERIFY(a > out); +} + +void tst_QQmlDebugJS::setBreakpointInScriptThatQuits() +{ + QFETCH(bool, qmlscene); + init(qmlscene, QUIT_QMLFILE); + + int sourceLine = 41; + + client->setBreakpoint(QLatin1String(SCRIPTREGEXP), QLatin1String(QUIT_QMLFILE), sourceLine, -1, true); + client->connect(); + QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped()))); + + QString jsonString(client->response); + QVariantMap value = client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap(); + + QVariantMap body = value.value("body").toMap(); + + QCOMPARE(body.value("sourceLine").toInt(), sourceLine); + QCOMPARE(QFileInfo(body.value("script").toMap().value("name").toString()).fileName(), QLatin1String(QUIT_QMLFILE)); + + client->continueDebugging(QJSDebugClient::Continue); + QVERIFY(process->waitForFinished()); + QCOMPARE(process->exitStatus(), QProcess::NormalExit); +} + +/* TODO fails because of a race condition when starting up the engine before the view +void tst_QQmlDebugJS::setBreakpointWhenAttaching() +{ + int sourceLine = 49; + QVERIFY(init(QLatin1String(TIMER_QMLFILE), false)); + + client->connect(); + //The breakpoint is in a timer loop so we can set it after connect(). + client->setBreakpoint(QLatin1String(SCRIPTREGEXP), QLatin1String(TIMER_QMLFILE), sourceLine); + QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped()))); +} +*/ + +#if 0 +void tst_QQmlDebugJS::setBreakpointOnEvent() +{ + QFAIL("Not implemented in V4."); + + //void setBreakpoint(QString type, QString target, int line = -1, int column = -1, bool enabled = false, QString condition = QString(), int ignoreCount = -1) + + init(TIMER_QMLFILE); + + client->setBreakpoint(QLatin1String(EVENT), QLatin1String("triggered"), -1, -1, true); + client->connect(); + QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped()))); + + QString jsonString(client->response); + QVariantMap value = client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap(); + + QVariantMap body = value.value("body").toMap(); + + QCOMPARE(QFileInfo(body.value("script").toMap().value("name").toString()).fileName(), QLatin1String(TIMER_QMLFILE)); +} +#endif + +void tst_QQmlDebugJS::clearBreakpoint() +{ + //void clearBreakpoint(int breakpoint); + QFETCH(bool, qmlscene); + + int sourceLine1 = 42; + int sourceLine2 = 43; + init(qmlscene, CHANGEBREAKPOINT_QMLFILE); + + client->connect(); + //The breakpoints are in a timer loop so we can set them after connect(). + //Furthermore the breakpoints should be hit in the right order because setting of breakpoints + //can only occur in the QML event loop. (see QCOMPARE for sourceLine2 below) + client->setBreakpoint(QLatin1String(SCRIPTREGEXP), QLatin1String(CHANGEBREAKPOINT_QMLFILE), sourceLine1, -1, true); + client->setBreakpoint(QLatin1String(SCRIPTREGEXP), QLatin1String(CHANGEBREAKPOINT_QMLFILE), sourceLine2, -1, true); + + QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped()))); + + //Will hit 1st brakpoint, change this breakpoint enable = false + QString jsonString(client->response); + QVariantMap value = client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap(); + + QVariantMap body = value.value("body").toMap(); + QList breakpointsHit = body.value("breakpoints").toList(); + + int breakpoint = breakpointsHit.at(0).toInt(); + client->clearBreakpoint(breakpoint); + + QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(result()))); + + //Continue with debugging + client->continueDebugging(QJSDebugClient::Continue); + //Hit 2nd breakpoint + QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped()))); + + //Continue with debugging + client->continueDebugging(QJSDebugClient::Continue); + //Should stop at 2nd breakpoint + QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped()))); + + jsonString = client->response; + value = client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap(); + + body = value.value("body").toMap(); + + QCOMPARE(body.value("sourceLine").toInt(), sourceLine2); +} + +void tst_QQmlDebugJS::setExceptionBreak() +{ + //void setExceptionBreak(QString type, bool enabled = false); + QFETCH(bool, qmlscene); + + init(qmlscene, EXCEPTION_QMLFILE); + client->setExceptionBreak(QJSDebugClient::All,true); + client->connect(); + QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped()))); +} + +void tst_QQmlDebugJS::stepNext() +{ + //void continueDebugging(StepAction stepAction, int stepCount = 1); + QFETCH(bool, qmlscene); + + int sourceLine = 42; + init(qmlscene, STEPACTION_QMLFILE); + + client->setBreakpoint(QLatin1String(SCRIPTREGEXP), QLatin1String(STEPACTION_QMLFILE), sourceLine, -1, true); + client->connect(); + QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped()))); + + client->continueDebugging(QJSDebugClient::Next); + QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped()))); + + QString jsonString(client->response); + QVariantMap value = client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap(); + + QVariantMap body = value.value("body").toMap(); + + QCOMPARE(body.value("sourceLine").toInt(), sourceLine + 1); + QCOMPARE(QFileInfo(body.value("script").toMap().value("name").toString()).fileName(), QLatin1String(STEPACTION_QMLFILE)); +} + +void tst_QQmlDebugJS::stepIn() +{ + //void continueDebugging(StepAction stepAction, int stepCount = 1); + QFETCH(bool, qmlscene); + + int sourceLine = 46; + int actualLine = 42; + init(qmlscene, STEPACTION_QMLFILE); + + client->setBreakpoint(QLatin1String(SCRIPTREGEXP), QLatin1String(STEPACTION_QMLFILE), sourceLine, 1, true); + client->connect(); + QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped()))); + + client->continueDebugging(QJSDebugClient::In); + QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped()))); + + QString jsonString(client->response); + QVariantMap value = client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap(); + + QVariantMap body = value.value("body").toMap(); + + QCOMPARE(body.value("sourceLine").toInt(), actualLine); + QCOMPARE(QFileInfo(body.value("script").toMap().value("name").toString()).fileName(), QLatin1String(STEPACTION_QMLFILE)); +} + +void tst_QQmlDebugJS::stepOut() +{ + //void continueDebugging(StepAction stepAction, int stepCount = 1); + QFETCH(bool, qmlscene); + + int sourceLine = 42; + int actualLine = 46; + init(qmlscene, STEPACTION_QMLFILE); + + client->setBreakpoint(QLatin1String(SCRIPTREGEXP), QLatin1String(STEPACTION_QMLFILE), sourceLine, -1, true); + client->connect(); + QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped()))); + + client->continueDebugging(QJSDebugClient::Out); + QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped()))); + + QString jsonString(client->response); + QVariantMap value = client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap(); + + QVariantMap body = value.value("body").toMap(); + + QCOMPARE(body.value("sourceLine").toInt(), actualLine); + QCOMPARE(QFileInfo(body.value("script").toMap().value("name").toString()).fileName(), QLatin1String(STEPACTION_QMLFILE)); +} + +void tst_QQmlDebugJS::continueDebugging() +{ + //void continueDebugging(StepAction stepAction, int stepCount = 1); + QFETCH(bool, qmlscene); + + int sourceLine1 = 46; + int sourceLine2 = 43; + init(qmlscene, STEPACTION_QMLFILE); + + client->setBreakpoint(QLatin1String(SCRIPTREGEXP), QLatin1String(STEPACTION_QMLFILE), sourceLine1, -1, true); + client->setBreakpoint(QLatin1String(SCRIPTREGEXP), QLatin1String(STEPACTION_QMLFILE), sourceLine2, -1, true); + client->connect(); + QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped()))); + + client->continueDebugging(QJSDebugClient::Continue); + QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped()))); + + QString jsonString(client->response); + QVariantMap value = client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap(); + + QVariantMap body = value.value("body").toMap(); + + QCOMPARE(body.value("sourceLine").toInt(), sourceLine2); + QCOMPARE(QFileInfo(body.value("script").toMap().value("name").toString()).fileName(), QLatin1String(STEPACTION_QMLFILE)); +} + +void tst_QQmlDebugJS::backtrace() +{ + //void backtrace(int fromFrame = -1, int toFrame = -1, bool bottom = false); + QFETCH(bool, qmlscene); + + int sourceLine = 39; + init(qmlscene, ONCOMPLETED_QMLFILE); + + client->setBreakpoint(QLatin1String(SCRIPTREGEXP), QLatin1String(ONCOMPLETED_QMLFILE), sourceLine, -1, true); + client->connect(); + QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped()))); + + client->backtrace(); + QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(result()))); +} + +void tst_QQmlDebugJS::getFrameDetails() +{ + //void frame(int number = -1); + QFETCH(bool, qmlscene); + + int sourceLine = 39; + init(qmlscene, ONCOMPLETED_QMLFILE); + + client->setBreakpoint(QLatin1String(SCRIPTREGEXP), QLatin1String(ONCOMPLETED_QMLFILE), sourceLine, -1, true); + client->connect(); + QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped()))); + + client->frame(); + QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(result()))); +} + +void tst_QQmlDebugJS::getScopeDetails() +{ + //void scope(int number = -1, int frameNumber = -1); + QFETCH(bool, qmlscene); + + int sourceLine = 39; + init(qmlscene, ONCOMPLETED_QMLFILE); + + client->setBreakpoint(QLatin1String(SCRIPTREGEXP), QLatin1String(ONCOMPLETED_QMLFILE), sourceLine, -1, true); + client->connect(); + QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped()))); + + client->scope(); + QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(result()))); +} + +#if 0 +void tst_QQmlDebugJS::evaluateInGlobalScope() +{ + //void evaluate(QString expr, bool global = false, bool disableBreak = false, int frame = -1, const QVariantMap &addContext = QVariantMap()); + + init(); + + client->connect(); + client->evaluate(QLatin1String("console.log('Hello World')"), true); + QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(evaluateResult()))); + + //Verify the value of 'print' + QString jsonString(client->response); + QVariantMap value = client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap(); + + QVariantMap body = value.value("body").toMap(); + + QCOMPARE(body.value("text").toString(),QLatin1String("undefined")); +} +#endif + +#if 0 +void tst_QQmlDebugJS::evaluateInLocalScope() +{ + //void evaluate(QString expr, bool global = false, bool disableBreak = false, int frame = -1, const QVariantMap &addContext = QVariantMap()); + + int sourceLine = 47; + init(ONCOMPLETED_QMLFILE); + + client->setBreakpoint(QLatin1String(SCRIPTREGEXP), QLatin1String(ONCOMPLETED_QMLFILE), sourceLine, -1, true); + client->connect(); + QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped()))); + + client->frame(); + QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(result()))); + + //Get the frame index + QString jsonString(client->response); + QVariantMap value = client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap(); + + QVariantMap body = value.value("body").toMap(); + + int frameIndex = body.value("index").toInt(); + + client->evaluate(QLatin1String("root.a"), frameIndex); + QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(evaluateResult()))); + + //Verify the value of 'timer.interval' + jsonString = client->response; + value = client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap(); + + body = value.value("body").toMap(); + + QCOMPARE(body.value("value").toInt(),10); +} +#endif + +void tst_QQmlDebugJS::getScripts() +{ + //void scripts(int types = -1, QList ids = QList(), bool includeSource = false, QVariant filter = QVariant()); + + QFETCH(bool, qmlscene); + init(qmlscene); + + client->setBreakpoint(QLatin1String(SCRIPTREGEXP), QString(TEST_QMLFILE), 40, -1, true); + client->connect(); + QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped()))); + + client->scripts(); + QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(scriptsResult()))); + QString jsonString(client->response); + QVariantMap value = client->parser.call(QJSValueList() + << QJSValue(jsonString)).toVariant().toMap(); + + QList scripts = value.value("body").toList(); + + QCOMPARE(scripts.count(), 1); + QVERIFY(scripts.first().toMap()[QStringLiteral("name")].toString().endsWith(QStringLiteral("data/test.qml"))); +} + +void tst_QQmlDebugJS::targetData() +{ + QTest::addColumn("qmlscene"); + QTest::newRow("custom") << false; + QTest::newRow("qmlscene") << true; +} + +QTEST_MAIN(tst_QQmlDebugJS) + +#include "tst_qqmldebugjs.moc" + diff --git a/tests/auto/qml/debugger/qqmldebugjs/qqmldebugjsserver/qqmldebugjsserver.cpp b/tests/auto/qml/debugger/qqmldebugjs/qqmldebugjsserver/qqmldebugjsserver.cpp new file mode 100644 index 0000000000..dd3416a78f --- /dev/null +++ b/tests/auto/qml/debugger/qqmldebugjs/qqmldebugjsserver/qqmldebugjsserver.cpp @@ -0,0 +1,48 @@ +/**************************************************************************** +** +** Copyright (C) 2015 The Qt Company Ltd. +** Contact: http://www.qt.io/licensing/ +** +** This file is part of the test suite of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL21$ +** 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 +** a written agreement between you and The Qt Company. For licensing terms +** and conditions see http://www.qt.io/terms-conditions. For further +** information use the contact form at http://www.qt.io/contact-us. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 or version 3 as published by the Free +** Software Foundation and appearing in the file LICENSE.LGPLv21 and +** LICENSE.LGPLv3 included in the packaging of this file. Please review the +** following information to ensure the GNU Lesser General Public License +** requirements will be met: https://www.gnu.org/licenses/lgpl.html and +** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** As a special exception, The Qt Company gives you certain additional +** rights. These rights are described in The Qt Company LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +#include +#include +#include + +int main(int argc, char *argv[]) +{ + QGuiApplication app(argc, argv); + QQmlEngine someWeirdEngine; // add another engine to cause some trouble + + QQmlApplicationEngine engine; + engine.load(QUrl::fromLocalFile(QLatin1String(argv[argc - 1]))); + + return app.exec(); +} + diff --git a/tests/auto/qml/debugger/qqmldebugjs/qqmldebugjsserver/qqmldebugjsserver.pro b/tests/auto/qml/debugger/qqmldebugjs/qqmldebugjsserver/qqmldebugjsserver.pro new file mode 100644 index 0000000000..837eaed9f1 --- /dev/null +++ b/tests/auto/qml/debugger/qqmldebugjs/qqmldebugjsserver/qqmldebugjsserver.pro @@ -0,0 +1,12 @@ +QT += qml testlib +osx:CONFIG -= app_bundle +CONFIG -= debug_and_release_target +INCLUDEPATH += ../../shared +SOURCES += qqmldebugjsserver.cpp +DEFINES += QT_QML_DEBUG_NO_WARNING + +DESTDIR = ../qqmldebugjs + +target.path = $$[QT_INSTALL_TESTS]/tst_qqmldebugjs +INSTALLS += target + diff --git a/tests/auto/qml/debugger/qqmldebugjs/tst_qqmldebugjs.cpp b/tests/auto/qml/debugger/qqmldebugjs/tst_qqmldebugjs.cpp deleted file mode 100644 index 13674fdb61..0000000000 --- a/tests/auto/qml/debugger/qqmldebugjs/tst_qqmldebugjs.cpp +++ /dev/null @@ -1,1467 +0,0 @@ -/**************************************************************************** -** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ -** -** This file is part of the test suite of the Qt Toolkit. -** -** $QT_BEGIN_LICENSE:LGPL21$ -** 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 -** a written agreement between you and The Qt Company. For licensing terms -** and conditions see http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. -** -** GNU Lesser General Public License Usage -** Alternatively, this file may be used under the terms of the GNU Lesser -** General Public License version 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. -** -** As a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. -** -** $QT_END_LICENSE$ -** -****************************************************************************/ - -//QQmlDebugTest -#include "debugutil_p.h" -#include "../../../shared/util.h" - -#include -#include -#include - -#include -#include -#include -#include -#include -#include -#include -#include - -#if defined (Q_OS_WINCE) -#undef IN -#undef OUT -#endif - -const char *V8REQUEST = "v8request"; -const char *V8MESSAGE = "v8message"; -const char *SEQ = "seq"; -const char *TYPE = "type"; -const char *COMMAND = "command"; -const char *ARGUMENTS = "arguments"; -const char *STEPACTION = "stepaction"; -const char *STEPCOUNT = "stepcount"; -const char *EXPRESSION = "expression"; -const char *FRAME = "frame"; -const char *GLOBAL = "global"; -const char *DISABLEBREAK = "disable_break"; -const char *HANDLES = "handles"; -const char *INCLUDESOURCE = "includeSource"; -const char *FROMFRAME = "fromFrame"; -const char *TOFRAME = "toFrame"; -const char *BOTTOM = "bottom"; -const char *NUMBER = "number"; -const char *FRAMENUMBER = "frameNumber"; -const char *TYPES = "types"; -const char *IDS = "ids"; -const char *FILTER = "filter"; -const char *FROMLINE = "fromLine"; -const char *TOLINE = "toLine"; -const char *TARGET = "target"; -const char *LINE = "line"; -const char *COLUMN = "column"; -const char *ENABLED = "enabled"; -const char *CONDITION = "condition"; -const char *IGNORECOUNT = "ignoreCount"; -const char *BREAKPOINT = "breakpoint"; -const char *FLAGS = "flags"; - -const char *CONTINEDEBUGGING = "continue"; -const char *EVALUATE = "evaluate"; -const char *LOOKUP = "lookup"; -const char *BACKTRACE = "backtrace"; -const char *SCOPE = "scope"; -const char *SCOPES = "scopes"; -const char *SCRIPTS = "scripts"; -const char *SOURCE = "source"; -const char *SETBREAKPOINT = "setbreakpoint"; -const char *CLEARBREAKPOINT = "clearbreakpoint"; -const char *SETEXCEPTIONBREAK = "setexceptionbreak"; -const char *VERSION = "version"; -const char *DISCONNECT = "disconnect"; -const char *GARBAGECOLLECTOR = "gc"; -//const char *PROFILE = "profile"; - -const char *CONNECT = "connect"; -const char *INTERRUPT = "interrupt"; - -const char *REQUEST = "request"; -const char *IN = "in"; -const char *NEXT = "next"; -const char *OUT = "out"; - -const char *FUNCTION = "function"; -const char *SCRIPT = "script"; -const char *SCRIPTREGEXP = "scriptRegExp"; -const char *EVENT = "event"; - -const char *ALL = "all"; -const char *UNCAUGHT = "uncaught"; - -//const char *PAUSE = "pause"; -//const char *RESUME = "resume"; - -const char *BLOCKMODE = "-qmljsdebugger=port:3771,3800,block"; -const char *NORMALMODE = "-qmljsdebugger=port:3771,3800"; -const char *BLOCKRESTRICTEDMODE = "-qmljsdebugger=port:3771,3800,block,services:V8Debugger"; -const char *NORMALRESTRICTEDMODE = "-qmljsdebugger=port:3771,3800,services:V8Debugger"; -const char *TEST_QMLFILE = "test.qml"; -const char *TEST_JSFILE = "test.js"; -const char *TIMER_QMLFILE = "timer.qml"; -const char *LOADJSFILE_QMLFILE = "loadjsfile.qml"; -const char *EXCEPTION_QMLFILE = "exception.qml"; -const char *ONCOMPLETED_QMLFILE = "oncompleted.qml"; -const char *CREATECOMPONENT_QMLFILE = "createComponent.qml"; -const char *CONDITION_QMLFILE = "condition.qml"; -const char *QUIT_QMLFILE = "quit.qml"; -const char *CHANGEBREAKPOINT_QMLFILE = "changeBreakpoint.qml"; -const char *STEPACTION_QMLFILE = "stepAction.qml"; -const char *BREAKPOINTRELOCATION_QMLFILE = "breakpointRelocation.qml"; - -#define VARIANTMAPINIT \ - QString obj("{}"); \ - QJSValue jsonVal = parser.call(QJSValueList() << obj); \ - jsonVal.setProperty(SEQ,QJSValue(seq++)); \ - jsonVal.setProperty(TYPE,REQUEST); - - -#undef QVERIFY -#define QVERIFY(statement) \ -do {\ - if (!QTest::qVerify((statement), #statement, "", __FILE__, __LINE__)) {\ - if (QTest::currentTestFailed()) \ - qDebug().nospace() << "\nDEBUGGEE OUTPUT:\n" << process->output();\ - return;\ - }\ -} while (0) - - -class QJSDebugClient; - -class tst_QQmlDebugJS : public QQmlDataTest -{ - Q_OBJECT - - void init(const QString &qmlFile = QString(TEST_QMLFILE), bool blockMode = true, - bool restrictServices = false); - -private slots: - void initTestCase(); - void cleanupTestCase(); - - void cleanup(); - - void connect_data(); - void connect(); - void interrupt(); - void getVersion(); -// void getVersionWhenAttaching(); - - void disconnect(); - - void setBreakpointInScriptOnCompleted(); - void setBreakpointInScriptOnComponentCreated(); - void setBreakpointInScriptOnTimerCallback(); - void setBreakpointInScriptInDifferentFile(); - void setBreakpointInScriptOnComment(); - void setBreakpointInScriptOnEmptyLine(); - void setBreakpointInScriptOnOptimizedBinding(); - void setBreakpointInScriptWithCondition(); - void setBreakpointInScriptThatQuits(); - //void setBreakpointInFunction(); //NOT SUPPORTED -// void setBreakpointOnEvent(); -// void setBreakpointWhenAttaching(); - - void clearBreakpoint(); - - void setExceptionBreak(); - - void stepNext(); - void stepIn(); - void stepOut(); - void continueDebugging(); - - void backtrace(); - - void getFrameDetails(); - - void getScopeDetails(); - -// void evaluateInGlobalScope(); // Not supported yet. -// void evaluateInLocalScope(); // Not supported yet. - - void getScripts(); - - // void profile(); //NOT SUPPORTED - - // void verifyQMLOptimizerDisabled(); - -private: - QQmlDebugProcess *process; - QJSDebugClient *client; - QQmlDebugConnection *connection; - QTime t; -}; - -class QJSDebugClient : public QQmlDebugClient -{ - Q_OBJECT -public: - enum StepAction - { - Continue, - In, - Out, - Next - }; - - enum Exception - { - All, - Uncaught - }; - -// enum ProfileCommand -// { -// Pause, -// Resume -// }; - - QJSDebugClient(QQmlDebugConnection *connection) - : QQmlDebugClient(QLatin1String("V8Debugger"), connection), - seq(0) - { - parser = jsEngine.evaluate(QLatin1String("JSON.parse")); - stringify = jsEngine.evaluate(QLatin1String("JSON.stringify")); - } - - void connect(); - void interrupt(); - - void continueDebugging(StepAction stepAction); - void evaluate(QString expr, bool global = false, bool disableBreak = false, int frame = -1, const QVariantMap &addContext = QVariantMap()); - void lookup(QList handles, bool includeSource = false); - void backtrace(int fromFrame = -1, int toFrame = -1, bool bottom = false); - void frame(int number = -1); - void scope(int number = -1, int frameNumber = -1); - void scripts(int types = 4, QList ids = QList(), bool includeSource = false, QVariant filter = QVariant()); - void setBreakpoint(QString type, QString target, int line = -1, int column = -1, bool enabled = true, QString condition = QString(), int ignoreCount = -1); - void clearBreakpoint(int breakpoint); - void setExceptionBreak(Exception type, bool enabled = false); - void version(); - //void profile(ProfileCommand command); //NOT SUPPORTED - void disconnect(); - -protected: - //inherited from QQmlDebugClient - void stateChanged(State state); - void messageReceived(const QByteArray &data); - -signals: - void enabled(); - void connected(); - void interruptRequested(); - void result(); - void stopped(); - void scriptsResult(); - void evaluateResult(); - -private: - void sendMessage(const QByteArray &); - void flushSendBuffer(); - QByteArray packMessage(const QByteArray &type, const QByteArray &message = QByteArray()); - -private: - QJSEngine jsEngine; - int seq; - - QList sendBuffer; -public: - QJSValue parser; - QJSValue stringify; - QByteArray response; - -}; - -void QJSDebugClient::connect() -{ - sendMessage(packMessage(CONNECT)); -} - -void QJSDebugClient::interrupt() -{ - sendMessage(packMessage(INTERRUPT)); -} - -void QJSDebugClient::continueDebugging(StepAction action) -{ - // { "seq" : , - // "type" : "request", - // "command" : "continue", - // "arguments" : { "stepaction" : <"in", "next" or "out">, - // "stepcount" : - // } - // } - VARIANTMAPINIT; - jsonVal.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(CONTINEDEBUGGING))); - - if (action != Continue) { - QJSValue args = parser.call(QJSValueList() << obj); - switch (action) { - case In: args.setProperty(QLatin1String(STEPACTION),QJSValue(QLatin1String(IN))); - break; - case Out: args.setProperty(QLatin1String(STEPACTION),QJSValue(QLatin1String(OUT))); - break; - case Next: args.setProperty(QLatin1String(STEPACTION),QJSValue(QLatin1String(NEXT))); - break; - default:break; - } - if (!args.isUndefined()) { - jsonVal.setProperty(QLatin1String(ARGUMENTS),args); - } - } - QJSValue json = stringify.call(QJSValueList() << jsonVal); - sendMessage(packMessage(V8REQUEST, json.toString().toUtf8())); -} - -void QJSDebugClient::evaluate(QString expr, bool global, bool disableBreak, int frame, const QVariantMap &/*addContext*/) -{ - // { "seq" : , - // "type" : "request", - // "command" : "evaluate", - // "arguments" : { "expression" : , - // "frame" : , - // "global" : , - // "disable_break" : , - // "additional_context" : [ - // { "name" : , "handle" : }, - // { "name" : , "handle" : }, - // ... - // ] - // } - // } - VARIANTMAPINIT; - jsonVal.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(EVALUATE))); - - QJSValue args = parser.call(QJSValueList() << obj); - args.setProperty(QLatin1String(EXPRESSION),QJSValue(expr)); - - if (frame != -1) - args.setProperty(QLatin1String(FRAME),QJSValue(frame)); - - if (global) - args.setProperty(QLatin1String(GLOBAL),QJSValue(global)); - - if (disableBreak) - args.setProperty(QLatin1String(DISABLEBREAK),QJSValue(disableBreak)); - - if (!args.isUndefined()) { - jsonVal.setProperty(QLatin1String(ARGUMENTS),args); - } - - QJSValue json = stringify.call(QJSValueList() << jsonVal); - sendMessage(packMessage(V8REQUEST, json.toString().toUtf8())); -} - -void QJSDebugClient::lookup(QList handles, bool includeSource) -{ - // { "seq" : , - // "type" : "request", - // "command" : "lookup", - // "arguments" : { "handles" : , - // "includeSource" : , - // } - // } - VARIANTMAPINIT; - jsonVal.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(LOOKUP))); - - QJSValue args = parser.call(QJSValueList() << obj); - - QString arr("[]"); - QJSValue array = parser.call(QJSValueList() << arr); - int index = 0; - foreach (int handle, handles) { - array.setProperty(index++,QJSValue(handle)); - } - args.setProperty(QLatin1String(HANDLES),array); - - if (includeSource) - args.setProperty(QLatin1String(INCLUDESOURCE),QJSValue(includeSource)); - - if (!args.isUndefined()) { - jsonVal.setProperty(QLatin1String(ARGUMENTS),args); - } - - QJSValue json = stringify.call(QJSValueList() << jsonVal); - sendMessage(packMessage(V8REQUEST, json.toString().toUtf8())); -} - -void QJSDebugClient::backtrace(int fromFrame, int toFrame, bool bottom) -{ - // { "seq" : , - // "type" : "request", - // "command" : "backtrace", - // "arguments" : { "fromFrame" : - // "toFrame" : - // "bottom" : - // } - // } - VARIANTMAPINIT; - jsonVal.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(BACKTRACE))); - - QJSValue args = parser.call(QJSValueList() << obj); - - if (fromFrame != -1) - args.setProperty(QLatin1String(FROMFRAME),QJSValue(fromFrame)); - - if (toFrame != -1) - args.setProperty(QLatin1String(TOFRAME),QJSValue(toFrame)); - - if (bottom) - args.setProperty(QLatin1String(BOTTOM),QJSValue(bottom)); - - if (!args.isUndefined()) { - jsonVal.setProperty(QLatin1String(ARGUMENTS),args); - } - - QJSValue json = stringify.call(QJSValueList() << jsonVal); - sendMessage(packMessage(V8REQUEST, json.toString().toUtf8())); -} - -void QJSDebugClient::frame(int number) -{ - // { "seq" : , - // "type" : "request", - // "command" : "frame", - // "arguments" : { "number" : - // } - // } - VARIANTMAPINIT; - jsonVal.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(FRAME))); - - if (number != -1) { - QJSValue args = parser.call(QJSValueList() << obj); - args.setProperty(QLatin1String(NUMBER),QJSValue(number)); - - if (!args.isUndefined()) { - jsonVal.setProperty(QLatin1String(ARGUMENTS),args); - } - } - - QJSValue json = stringify.call(QJSValueList() << jsonVal); - sendMessage(packMessage(V8REQUEST, json.toString().toUtf8())); -} - -void QJSDebugClient::scope(int number, int frameNumber) -{ - // { "seq" : , - // "type" : "request", - // "command" : "scope", - // "arguments" : { "number" : - // "frameNumber" : - // } - // } - VARIANTMAPINIT; - jsonVal.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(SCOPE))); - - if (number != -1) { - QJSValue args = parser.call(QJSValueList() << obj); - args.setProperty(QLatin1String(NUMBER),QJSValue(number)); - - if (frameNumber != -1) - args.setProperty(QLatin1String(FRAMENUMBER),QJSValue(frameNumber)); - - if (!args.isUndefined()) { - jsonVal.setProperty(QLatin1String(ARGUMENTS),args); - } - } - - QJSValue json = stringify.call(QJSValueList() << jsonVal); - sendMessage(packMessage(V8REQUEST, json.toString().toUtf8())); -} - -void QJSDebugClient::scripts(int types, QList ids, bool includeSource, QVariant /*filter*/) -{ - // { "seq" : , - // "type" : "request", - // "command" : "scripts", - // "arguments" : { "types" : - // "ids" : - // "includeSource" : - // "filter" : - // } - // } - VARIANTMAPINIT; - jsonVal.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(SCRIPTS))); - - QJSValue args = parser.call(QJSValueList() << obj); - args.setProperty(QLatin1String(TYPES),QJSValue(types)); - - if (ids.count()) { - QString arr("[]"); - QJSValue array = parser.call(QJSValueList() << arr); - int index = 0; - foreach (int id, ids) { - array.setProperty(index++,QJSValue(id)); - } - args.setProperty(QLatin1String(IDS),array); - } - - if (includeSource) - args.setProperty(QLatin1String(INCLUDESOURCE),QJSValue(includeSource)); - - if (!args.isUndefined()) { - jsonVal.setProperty(QLatin1String(ARGUMENTS),args); - } - - QJSValue json = stringify.call(QJSValueList() << jsonVal); - sendMessage(packMessage(V8REQUEST, json.toString().toUtf8())); -} - -void QJSDebugClient::setBreakpoint(QString type, QString target, int line, int column, bool enabled, QString condition, int ignoreCount) -{ - // { "seq" : , - // "type" : "request", - // "command" : "setbreakpoint", - // "arguments" : { "type" : <"function" or "script" or "scriptId" or "scriptRegExp"> - // "target" : - // "line" : - // "column" : - // "enabled" : - // "condition" : - // "ignoreCount" : - // } - // } - - if (type == QLatin1String(EVENT)) { - QPacket rs(connection()->currentDataStreamVersion()); - rs << target.toUtf8() << enabled; - sendMessage(packMessage(QByteArray("breakonsignal"), rs.data())); - } else { - VARIANTMAPINIT; - jsonVal.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(SETBREAKPOINT))); - - QJSValue args = parser.call(QJSValueList() << obj); - - args.setProperty(QLatin1String(TYPE),QJSValue(type)); - args.setProperty(QLatin1String(TARGET),QJSValue(target)); - - if (line != -1) - args.setProperty(QLatin1String(LINE),QJSValue(line)); - - if (column != -1) - args.setProperty(QLatin1String(COLUMN),QJSValue(column)); - - args.setProperty(QLatin1String(ENABLED),QJSValue(enabled)); - - if (!condition.isEmpty()) - args.setProperty(QLatin1String(CONDITION),QJSValue(condition)); - - if (ignoreCount != -1) - args.setProperty(QLatin1String(IGNORECOUNT),QJSValue(ignoreCount)); - - if (!args.isUndefined()) { - jsonVal.setProperty(QLatin1String(ARGUMENTS),args); - } - - QJSValue json = stringify.call(QJSValueList() << jsonVal); - sendMessage(packMessage(V8REQUEST, json.toString().toUtf8())); - } -} - -void QJSDebugClient::clearBreakpoint(int breakpoint) -{ - // { "seq" : , - // "type" : "request", - // "command" : "clearbreakpoint", - // "arguments" : { "breakpoint" : - // } - // } - VARIANTMAPINIT; - jsonVal.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(CLEARBREAKPOINT))); - - QJSValue args = parser.call(QJSValueList() << obj); - - args.setProperty(QLatin1String(BREAKPOINT),QJSValue(breakpoint)); - - if (!args.isUndefined()) { - jsonVal.setProperty(QLatin1String(ARGUMENTS),args); - } - - QJSValue json = stringify.call(QJSValueList() << jsonVal); - sendMessage(packMessage(V8REQUEST, json.toString().toUtf8())); -} - -void QJSDebugClient::setExceptionBreak(Exception type, bool enabled) -{ - // { "seq" : , - // "type" : "request", - // "command" : "setexceptionbreak", - // "arguments" : { "type" : , - // "enabled" : - // } - // } - VARIANTMAPINIT; - jsonVal.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(SETEXCEPTIONBREAK))); - - QJSValue args = parser.call(QJSValueList() << obj); - - if (type == All) - args.setProperty(QLatin1String(TYPE),QJSValue(QLatin1String(ALL))); - else if (type == Uncaught) - args.setProperty(QLatin1String(TYPE),QJSValue(QLatin1String(UNCAUGHT))); - - if (enabled) - args.setProperty(QLatin1String(ENABLED),QJSValue(enabled)); - - if (!args.isUndefined()) { - jsonVal.setProperty(QLatin1String(ARGUMENTS),args); - } - - QJSValue json = stringify.call(QJSValueList() << jsonVal); - sendMessage(packMessage(V8REQUEST, json.toString().toUtf8())); -} - -void QJSDebugClient::version() -{ - // { "seq" : , - // "type" : "request", - // "command" : "version", - // } - VARIANTMAPINIT; - jsonVal.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(VERSION))); - - QJSValue json = stringify.call(QJSValueList() << jsonVal); - sendMessage(packMessage(V8REQUEST, json.toString().toUtf8())); -} - -//void QJSDebugClient::profile(ProfileCommand command) -//{ -//// { "seq" : , -//// "type" : "request", -//// "command" : "profile", -//// "arguments" : { "command" : "resume" or "pause" } -//// } -// VARIANTMAPINIT; -// jsonVal.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(PROFILE))); - -// QJSValue args = parser.call(QJSValueList() << obj); - -// if (command == Resume) -// args.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(RESUME))); -// else -// args.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(PAUSE))); - -// args.setProperty(QLatin1String("modules"),QJSValue(1)); -// if (!args.isUndefined()) { -// jsonVal.setProperty(QLatin1String(ARGUMENTS),args); -// } - -// QJSValue json = stringify.call(QJSValueList() << jsonVal); -// sendMessage(packMessage(V8REQUEST, json.toString().toUtf8())); -//} - -void QJSDebugClient::disconnect() -{ - // { "seq" : , - // "type" : "request", - // "command" : "disconnect", - // } - VARIANTMAPINIT; - jsonVal.setProperty(QLatin1String(COMMAND),QJSValue(QLatin1String(DISCONNECT))); - - QJSValue json = stringify.call(QJSValueList() << jsonVal); - sendMessage(packMessage(DISCONNECT, json.toString().toUtf8())); -} - -void QJSDebugClient::stateChanged(State state) -{ - if (state == Enabled) { - flushSendBuffer(); - emit enabled(); - } -} - -void QJSDebugClient::messageReceived(const QByteArray &data) -{ - QPacket ds(connection()->currentDataStreamVersion(), data); - QByteArray command; - ds >> command; - - if (command == "V8DEBUG") { - QByteArray type; - ds >> type >> response; - - if (type == CONNECT) { - emit connected(); - - } else if (type == INTERRUPT) { - emit interruptRequested(); - - } else if (type == V8MESSAGE) { - QString jsonString(response); - QVariantMap value = parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap(); - QString type = value.value("type").toString(); - - if (type == "response") { - - if (!value.value("success").toBool()) { -// qDebug() << "Error: The test case will fail since no signal is emitted"; - return; - } - - QString debugCommand(value.value("command").toString()); - if (debugCommand == "backtrace" || - debugCommand == "lookup" || - debugCommand == "setbreakpoint" || - debugCommand == "evaluate" || - debugCommand == "version" || - debugCommand == "disconnect" || - debugCommand == "gc" || - debugCommand == "changebreakpoint" || - debugCommand == "clearbreakpoint" || - debugCommand == "frame" || - debugCommand == "scope" || - debugCommand == "scopes" || - debugCommand == "scripts" || - debugCommand == "source" || - debugCommand == "setexceptionbreak" /*|| - debugCommand == "profile"*/) { - emit result(); - - } else { - // DO NOTHING - } - //Emit separate signals for scripts ane evaluate - //as the associated test cases are flaky - if (debugCommand == "scripts") - emit scriptsResult(); - if (debugCommand == "evaluate") - emit evaluateResult(); - - } else if (type == QLatin1String(EVENT)) { - QString event(value.value(QLatin1String(EVENT)).toString()); - - if (event == "break" || - event == "exception") - emit stopped(); - } - - } - } -} - -void QJSDebugClient::sendMessage(const QByteArray &msg) -{ - if (state() == Enabled) { - QQmlDebugClient::sendMessage(msg); - } else { - sendBuffer.append(msg); - } -} - -void QJSDebugClient::flushSendBuffer() -{ - foreach (const QByteArray &msg, sendBuffer) - QQmlDebugClient::sendMessage(msg); - sendBuffer.clear(); -} - -QByteArray QJSDebugClient::packMessage(const QByteArray &type, const QByteArray &message) -{ - QPacket rs(connection()->currentDataStreamVersion()); - QByteArray cmd = "V8DEBUG"; - rs << cmd << type << message; - return rs.data(); -} - -void tst_QQmlDebugJS::initTestCase() -{ - QQmlDataTest::initTestCase(); - t.start(); - process = 0; - client = 0; - connection = 0; -} - -void tst_QQmlDebugJS::cleanupTestCase() -{ - if (process) { - process->stop(); - delete process; - } - - if (client) - delete client; - - if (connection) - delete connection; - -// qDebug() << "Time Elapsed:" << t.elapsed(); -} - -void tst_QQmlDebugJS::init(const QString &qmlFile, bool blockMode, bool restrictServices) -{ - connection = new QQmlDebugConnection(); - process = new QQmlDebugProcess(QLibraryInfo::location(QLibraryInfo::BinariesPath) + "/qmlscene", this); - client = new QJSDebugClient(connection); - QList others = QQmlDebugTest::createOtherClients(connection); - - const char *args = 0; - if (blockMode) - args = restrictServices ? BLOCKRESTRICTEDMODE : BLOCKMODE; - else - args = restrictServices ? NORMALRESTRICTEDMODE : NORMALMODE; - - process->start(QStringList() << QLatin1String(args) << testFile(qmlFile)); - - QVERIFY(process->waitForSessionStart()); - - const int port = process->debugPort(); - connection->connectToHost("127.0.0.1", port); - QVERIFY(connection->waitForConnected()); - - - if (client->state() != QQmlDebugClient::Enabled) - QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(enabled()))); - - foreach (QQmlDebugClient *otherClient, others) - QCOMPARE(otherClient->state(), restrictServices ? QQmlDebugClient::Unavailable : - QQmlDebugClient::Enabled); - qDeleteAll(others); -} - -void tst_QQmlDebugJS::cleanup() -{ - if (QTest::currentTestFailed()) { - qDebug() << "Process State:" << process->state(); - qDebug() << "Application Output:" << process->output(); - } - - if (process) { - process->stop(); - delete process; - } - - if (client) - delete client; - - if (connection) - delete connection; - - process = 0; - client = 0; - connection = 0; -} - -void tst_QQmlDebugJS::connect_data() -{ - QTest::addColumn("blockMode"); - QTest::addColumn("restrictMode"); - QTest::newRow("normal/unrestricted") << false << false; - QTest::newRow("block/unrestricted") << true << false; - QTest::newRow("normal/restricted") << false << true; - QTest::newRow("block/restricted") << true << true; -} - -void tst_QQmlDebugJS::connect() -{ - QFETCH(bool, blockMode); - QFETCH(bool, restrictMode); - init(QString(TEST_QMLFILE), blockMode, restrictMode); - client->connect(); - QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(connected()))); -} - -void tst_QQmlDebugJS::interrupt() -{ - //void connect() - - init(); - client->connect(); - - client->interrupt(); - QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(interruptRequested()))); -} - -void tst_QQmlDebugJS::getVersion() -{ - //void version() - - init(); - client->connect(); - QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(connected()))); - - client->version(); - QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(result()))); -} - -/* TODO fails because of a race condition when starting up the engine before the view -void tst_QQmlDebugJS::getVersionWhenAttaching() -{ - //void version() - - QVERIFY(init(QLatin1String(TIMER_QMLFILE), false)); - client->connect(); - - client->version(); - QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(result()))); -} -*/ - -void tst_QQmlDebugJS::disconnect() -{ - //void disconnect() - - init(); - client->connect(); - - client->disconnect(); - QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(result()))); -} - -void tst_QQmlDebugJS::setBreakpointInScriptOnCompleted() -{ - //void setBreakpoint(QString type, QString target, int line = -1, int column = -1, bool enabled = false, QString condition = QString(), int ignoreCount = -1) - - int sourceLine = 39; - init(ONCOMPLETED_QMLFILE); - - client->setBreakpoint(QLatin1String(SCRIPTREGEXP), QLatin1String(ONCOMPLETED_QMLFILE), sourceLine, -1, true); - client->connect(); - QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped()))); - - QString jsonString(client->response); - QVariantMap value = client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap(); - - QVariantMap body = value.value("body").toMap(); - - QCOMPARE(body.value("sourceLine").toInt(), sourceLine); - QCOMPARE(QFileInfo(body.value("script").toMap().value("name").toString()).fileName(), QLatin1String(ONCOMPLETED_QMLFILE)); -} - -void tst_QQmlDebugJS::setBreakpointInScriptOnComponentCreated() -{ - //void setBreakpoint(QString type, QString target, int line = -1, int column = -1, bool enabled = false, QString condition = QString(), int ignoreCount = -1) - - int sourceLine = 39; - init(CREATECOMPONENT_QMLFILE); - - client->setBreakpoint(QLatin1String(SCRIPTREGEXP), QLatin1String(ONCOMPLETED_QMLFILE), sourceLine, -1, true); - client->connect(); - QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped()))); - - QString jsonString(client->response); - QVariantMap value = client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap(); - - QVariantMap body = value.value("body").toMap(); - - QCOMPARE(body.value("sourceLine").toInt(), sourceLine); - QCOMPARE(QFileInfo(body.value("script").toMap().value("name").toString()).fileName(), QLatin1String(ONCOMPLETED_QMLFILE)); -} - -void tst_QQmlDebugJS::setBreakpointInScriptOnTimerCallback() -{ - int sourceLine = 40; - init(TIMER_QMLFILE); - - client->connect(); - //We can set the breakpoint after connect() here because the timer is repeating and if we miss - //its first iteration we can still catch the second one. - client->setBreakpoint(QLatin1String(SCRIPTREGEXP), QLatin1String(TIMER_QMLFILE), sourceLine, -1, true); - QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped()))); - - QString jsonString(client->response); - QVariantMap value = client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap(); - - QVariantMap body = value.value("body").toMap(); - - QCOMPARE(body.value("sourceLine").toInt(), sourceLine); - QCOMPARE(QFileInfo(body.value("script").toMap().value("name").toString()).fileName(), QLatin1String(TIMER_QMLFILE)); -} - -void tst_QQmlDebugJS::setBreakpointInScriptInDifferentFile() -{ - //void setBreakpoint(QString type, QString target, int line = -1, int column = -1, bool enabled = false, QString condition = QString(), int ignoreCount = -1) - - int sourceLine = 35; - init(LOADJSFILE_QMLFILE); - - client->setBreakpoint(QLatin1String(SCRIPTREGEXP), QLatin1String(TEST_JSFILE), sourceLine, -1, true); - client->connect(); - QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped()))); - - QString jsonString(client->response); - QVariantMap value = client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap(); - - QVariantMap body = value.value("body").toMap(); - - QCOMPARE(body.value("sourceLine").toInt(), sourceLine); - QCOMPARE(QFileInfo(body.value("script").toMap().value("name").toString()).fileName(), QLatin1String(TEST_JSFILE)); -} - -void tst_QQmlDebugJS::setBreakpointInScriptOnComment() -{ - //void setBreakpoint(QString type, QString target, int line = -1, int column = -1, bool enabled = false, QString condition = QString(), int ignoreCount = -1) - - int sourceLine = 39; - int actualLine = 41; - init(BREAKPOINTRELOCATION_QMLFILE); - - client->setBreakpoint(QLatin1String(SCRIPTREGEXP), QLatin1String(BREAKPOINTRELOCATION_QMLFILE), sourceLine, -1, true); - client->connect(); - QEXPECT_FAIL("", "Relocation of breakpoints is disabled right now", Abort); - QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped()), 1)); - - QString jsonString(client->response); - QVariantMap value = client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap(); - - QVariantMap body = value.value("body").toMap(); - - QCOMPARE(body.value("sourceLine").toInt(), actualLine); - QCOMPARE(QFileInfo(body.value("script").toMap().value("name").toString()).fileName(), QLatin1String(BREAKPOINTRELOCATION_QMLFILE)); -} - -void tst_QQmlDebugJS::setBreakpointInScriptOnEmptyLine() -{ - //void setBreakpoint(QString type, QString target, int line = -1, int column = -1, bool enabled = false, QString condition = QString(), int ignoreCount = -1) - - int sourceLine = 40; - int actualLine = 41; - init(BREAKPOINTRELOCATION_QMLFILE); - - client->setBreakpoint(QLatin1String(SCRIPTREGEXP), QLatin1String(BREAKPOINTRELOCATION_QMLFILE), sourceLine, -1, true); - client->connect(); - QEXPECT_FAIL("", "Relocation of breakpoints is disabled right now", Abort); - QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped()), 1)); - - QString jsonString(client->response); - QVariantMap value = client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap(); - - QVariantMap body = value.value("body").toMap(); - - QCOMPARE(body.value("sourceLine").toInt(), actualLine); - QCOMPARE(QFileInfo(body.value("script").toMap().value("name").toString()).fileName(), QLatin1String(BREAKPOINTRELOCATION_QMLFILE)); -} - -void tst_QQmlDebugJS::setBreakpointInScriptOnOptimizedBinding() -{ - //void setBreakpoint(QString type, QString target, int line = -1, int column = -1, bool enabled = false, QString condition = QString(), int ignoreCount = -1) - - int sourceLine = 44; - init(BREAKPOINTRELOCATION_QMLFILE); - - client->setBreakpoint(QLatin1String(SCRIPTREGEXP), QLatin1String(BREAKPOINTRELOCATION_QMLFILE), sourceLine, -1, true); - client->connect(); - QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped()))); - - QString jsonString(client->response); - QVariantMap value = client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap(); - - QVariantMap body = value.value("body").toMap(); - - QCOMPARE(body.value("sourceLine").toInt(), sourceLine); - QCOMPARE(QFileInfo(body.value("script").toMap().value("name").toString()).fileName(), QLatin1String(BREAKPOINTRELOCATION_QMLFILE)); -} - -void tst_QQmlDebugJS::setBreakpointInScriptWithCondition() -{ - int out = 10; - int sourceLine = 42; - init(CONDITION_QMLFILE); - - client->connect(); - //The breakpoint is in a timer loop so we can set it after connect(). - client->setBreakpoint(QLatin1String(SCRIPTREGEXP), QLatin1String(CONDITION_QMLFILE), sourceLine, 1, true, QLatin1String("a > 10")); - QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped()))); - - //Get the frame index - QString jsonString = client->response; - QVariantMap value = client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap(); - - { - QVariantMap body = value.value("body").toMap(); - int frameIndex = body.value("index").toInt(); - - //Verify the value of 'result' - client->evaluate(QLatin1String("a"),frameIndex); - QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(result()))); - } - - jsonString = client->response; - QJSValue val = client->parser.call(QJSValueList() << QJSValue(jsonString)); - QVERIFY(val.isObject()); - QJSValue body = val.property(QStringLiteral("body")); - QVERIFY(body.isObject()); - val = body.property("value"); - QVERIFY(val.isNumber()); - - const int a = val.toInt(); - QVERIFY(a > out); -} - -void tst_QQmlDebugJS::setBreakpointInScriptThatQuits() -{ - init(QUIT_QMLFILE); - - int sourceLine = 41; - - client->setBreakpoint(QLatin1String(SCRIPTREGEXP), QLatin1String(QUIT_QMLFILE), sourceLine, -1, true); - client->connect(); - QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped()))); - - QString jsonString(client->response); - QVariantMap value = client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap(); - - QVariantMap body = value.value("body").toMap(); - - QCOMPARE(body.value("sourceLine").toInt(), sourceLine); - QCOMPARE(QFileInfo(body.value("script").toMap().value("name").toString()).fileName(), QLatin1String(QUIT_QMLFILE)); - - client->continueDebugging(QJSDebugClient::Continue); - QVERIFY(process->waitForFinished()); - QCOMPARE(process->exitStatus(), QProcess::NormalExit); -} - -/* TODO fails because of a race condition when starting up the engine before the view -void tst_QQmlDebugJS::setBreakpointWhenAttaching() -{ - int sourceLine = 49; - QVERIFY(init(QLatin1String(TIMER_QMLFILE), false)); - - client->connect(); - //The breakpoint is in a timer loop so we can set it after connect(). - client->setBreakpoint(QLatin1String(SCRIPTREGEXP), QLatin1String(TIMER_QMLFILE), sourceLine); - QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped()))); -} -*/ - -#if 0 -void tst_QQmlDebugJS::setBreakpointOnEvent() -{ - QFAIL("Not implemented in V4."); - - //void setBreakpoint(QString type, QString target, int line = -1, int column = -1, bool enabled = false, QString condition = QString(), int ignoreCount = -1) - - init(TIMER_QMLFILE); - - client->setBreakpoint(QLatin1String(EVENT), QLatin1String("triggered"), -1, -1, true); - client->connect(); - QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped()))); - - QString jsonString(client->response); - QVariantMap value = client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap(); - - QVariantMap body = value.value("body").toMap(); - - QCOMPARE(QFileInfo(body.value("script").toMap().value("name").toString()).fileName(), QLatin1String(TIMER_QMLFILE)); -} -#endif - -void tst_QQmlDebugJS::clearBreakpoint() -{ - //void clearBreakpoint(int breakpoint); - - int sourceLine1 = 42; - int sourceLine2 = 43; - init(CHANGEBREAKPOINT_QMLFILE); - - client->connect(); - //The breakpoints are in a timer loop so we can set them after connect(). - //Furthermore the breakpoints should be hit in the right order because setting of breakpoints - //can only occur in the QML event loop. (see QCOMPARE for sourceLine2 below) - client->setBreakpoint(QLatin1String(SCRIPTREGEXP), QLatin1String(CHANGEBREAKPOINT_QMLFILE), sourceLine1, -1, true); - client->setBreakpoint(QLatin1String(SCRIPTREGEXP), QLatin1String(CHANGEBREAKPOINT_QMLFILE), sourceLine2, -1, true); - - QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped()))); - - //Will hit 1st brakpoint, change this breakpoint enable = false - QString jsonString(client->response); - QVariantMap value = client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap(); - - QVariantMap body = value.value("body").toMap(); - QList breakpointsHit = body.value("breakpoints").toList(); - - int breakpoint = breakpointsHit.at(0).toInt(); - client->clearBreakpoint(breakpoint); - - QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(result()))); - - //Continue with debugging - client->continueDebugging(QJSDebugClient::Continue); - //Hit 2nd breakpoint - QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped()))); - - //Continue with debugging - client->continueDebugging(QJSDebugClient::Continue); - //Should stop at 2nd breakpoint - QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped()))); - - jsonString = client->response; - value = client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap(); - - body = value.value("body").toMap(); - - QCOMPARE(body.value("sourceLine").toInt(), sourceLine2); -} - -void tst_QQmlDebugJS::setExceptionBreak() -{ - //void setExceptionBreak(QString type, bool enabled = false); - - init(EXCEPTION_QMLFILE); - client->setExceptionBreak(QJSDebugClient::All,true); - client->connect(); - QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped()))); -} - -void tst_QQmlDebugJS::stepNext() -{ - //void continueDebugging(StepAction stepAction, int stepCount = 1); - - int sourceLine = 42; - init(STEPACTION_QMLFILE); - - client->setBreakpoint(QLatin1String(SCRIPTREGEXP), QLatin1String(STEPACTION_QMLFILE), sourceLine, -1, true); - client->connect(); - QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped()))); - - client->continueDebugging(QJSDebugClient::Next); - QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped()))); - - QString jsonString(client->response); - QVariantMap value = client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap(); - - QVariantMap body = value.value("body").toMap(); - - QCOMPARE(body.value("sourceLine").toInt(), sourceLine + 1); - QCOMPARE(QFileInfo(body.value("script").toMap().value("name").toString()).fileName(), QLatin1String(STEPACTION_QMLFILE)); -} - -void tst_QQmlDebugJS::stepIn() -{ - //void continueDebugging(StepAction stepAction, int stepCount = 1); - - int sourceLine = 46; - int actualLine = 42; - init(STEPACTION_QMLFILE); - - client->setBreakpoint(QLatin1String(SCRIPTREGEXP), QLatin1String(STEPACTION_QMLFILE), sourceLine, 1, true); - client->connect(); - QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped()))); - - client->continueDebugging(QJSDebugClient::In); - QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped()))); - - QString jsonString(client->response); - QVariantMap value = client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap(); - - QVariantMap body = value.value("body").toMap(); - - QCOMPARE(body.value("sourceLine").toInt(), actualLine); - QCOMPARE(QFileInfo(body.value("script").toMap().value("name").toString()).fileName(), QLatin1String(STEPACTION_QMLFILE)); -} - -void tst_QQmlDebugJS::stepOut() -{ - //void continueDebugging(StepAction stepAction, int stepCount = 1); - - int sourceLine = 42; - int actualLine = 46; - init(STEPACTION_QMLFILE); - - client->setBreakpoint(QLatin1String(SCRIPTREGEXP), QLatin1String(STEPACTION_QMLFILE), sourceLine, -1, true); - client->connect(); - QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped()))); - - client->continueDebugging(QJSDebugClient::Out); - QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped()))); - - QString jsonString(client->response); - QVariantMap value = client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap(); - - QVariantMap body = value.value("body").toMap(); - - QCOMPARE(body.value("sourceLine").toInt(), actualLine); - QCOMPARE(QFileInfo(body.value("script").toMap().value("name").toString()).fileName(), QLatin1String(STEPACTION_QMLFILE)); -} - -void tst_QQmlDebugJS::continueDebugging() -{ - //void continueDebugging(StepAction stepAction, int stepCount = 1); - - int sourceLine1 = 46; - int sourceLine2 = 43; - init(STEPACTION_QMLFILE); - - client->setBreakpoint(QLatin1String(SCRIPTREGEXP), QLatin1String(STEPACTION_QMLFILE), sourceLine1, -1, true); - client->setBreakpoint(QLatin1String(SCRIPTREGEXP), QLatin1String(STEPACTION_QMLFILE), sourceLine2, -1, true); - client->connect(); - QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped()))); - - client->continueDebugging(QJSDebugClient::Continue); - QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped()))); - - QString jsonString(client->response); - QVariantMap value = client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap(); - - QVariantMap body = value.value("body").toMap(); - - QCOMPARE(body.value("sourceLine").toInt(), sourceLine2); - QCOMPARE(QFileInfo(body.value("script").toMap().value("name").toString()).fileName(), QLatin1String(STEPACTION_QMLFILE)); -} - -void tst_QQmlDebugJS::backtrace() -{ - //void backtrace(int fromFrame = -1, int toFrame = -1, bool bottom = false); - - int sourceLine = 39; - init(ONCOMPLETED_QMLFILE); - - client->setBreakpoint(QLatin1String(SCRIPTREGEXP), QLatin1String(ONCOMPLETED_QMLFILE), sourceLine, -1, true); - client->connect(); - QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped()))); - - client->backtrace(); - QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(result()))); -} - -void tst_QQmlDebugJS::getFrameDetails() -{ - //void frame(int number = -1); - - int sourceLine = 39; - init(ONCOMPLETED_QMLFILE); - - client->setBreakpoint(QLatin1String(SCRIPTREGEXP), QLatin1String(ONCOMPLETED_QMLFILE), sourceLine, -1, true); - client->connect(); - QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped()))); - - client->frame(); - QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(result()))); -} - -void tst_QQmlDebugJS::getScopeDetails() -{ - //void scope(int number = -1, int frameNumber = -1); - - int sourceLine = 39; - init(ONCOMPLETED_QMLFILE); - - client->setBreakpoint(QLatin1String(SCRIPTREGEXP), QLatin1String(ONCOMPLETED_QMLFILE), sourceLine, -1, true); - client->connect(); - QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped()))); - - client->scope(); - QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(result()))); -} - -#if 0 -void tst_QQmlDebugJS::evaluateInGlobalScope() -{ - //void evaluate(QString expr, bool global = false, bool disableBreak = false, int frame = -1, const QVariantMap &addContext = QVariantMap()); - - init(); - - client->connect(); - client->evaluate(QLatin1String("console.log('Hello World')"), true); - QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(evaluateResult()))); - - //Verify the value of 'print' - QString jsonString(client->response); - QVariantMap value = client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap(); - - QVariantMap body = value.value("body").toMap(); - - QCOMPARE(body.value("text").toString(),QLatin1String("undefined")); -} -#endif - -#if 0 -void tst_QQmlDebugJS::evaluateInLocalScope() -{ - //void evaluate(QString expr, bool global = false, bool disableBreak = false, int frame = -1, const QVariantMap &addContext = QVariantMap()); - - int sourceLine = 47; - init(ONCOMPLETED_QMLFILE); - - client->setBreakpoint(QLatin1String(SCRIPTREGEXP), QLatin1String(ONCOMPLETED_QMLFILE), sourceLine, -1, true); - client->connect(); - QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped()))); - - client->frame(); - QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(result()))); - - //Get the frame index - QString jsonString(client->response); - QVariantMap value = client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap(); - - QVariantMap body = value.value("body").toMap(); - - int frameIndex = body.value("index").toInt(); - - client->evaluate(QLatin1String("root.a"), frameIndex); - QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(evaluateResult()))); - - //Verify the value of 'timer.interval' - jsonString = client->response; - value = client->parser.call(QJSValueList() << QJSValue(jsonString)).toVariant().toMap(); - - body = value.value("body").toMap(); - - QCOMPARE(body.value("value").toInt(),10); -} -#endif - -void tst_QQmlDebugJS::getScripts() -{ - //void scripts(int types = -1, QList ids = QList(), bool includeSource = false, QVariant filter = QVariant()); - - init(); - - client->setBreakpoint(QLatin1String(SCRIPTREGEXP), QString(TEST_QMLFILE), 40, -1, true); - client->connect(); - QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(stopped()))); - - client->scripts(); - QVERIFY(QQmlDebugTest::waitForSignal(client, SIGNAL(scriptsResult()))); - QString jsonString(client->response); - QVariantMap value = client->parser.call(QJSValueList() - << QJSValue(jsonString)).toVariant().toMap(); - - QList scripts = value.value("body").toList(); - - QCOMPARE(scripts.count(), 1); - QVERIFY(scripts.first().toMap()[QStringLiteral("name")].toString().endsWith(QStringLiteral("data/test.qml"))); -} - -QTEST_MAIN(tst_QQmlDebugJS) - -#include "tst_qqmldebugjs.moc" - -- cgit v1.2.3