File indexing completed on 2024-09-08 03:40:36
0001 /* 0002 This file is part of the KDE project 0003 SPDX-FileCopyrightText: 2001, 2003 Peter Kelly <pmk@post.com> 0004 SPDX-FileCopyrightText: 2003, 2004 Stephan Kulow <coolo@kde.org> 0005 SPDX-FileCopyrightText: 2004 Dirk Mueller <mueller@kde.org> 0006 SPDX-FileCopyrightText: 2006, 2007 Leo Savernik <l.savernik@aon.at> 0007 0008 SPDX-License-Identifier: LGPL-2.0-or-later 0009 */ 0010 0011 // BEGIN Includes 0012 #include "testutils.h" 0013 0014 #include "kateconfig.h" 0015 #include "katedocument.h" 0016 #include "katescripthelpers.h" 0017 #include "kateview.h" 0018 #include "ktexteditor/cursor.h" 0019 #include "ktexteditor/range.h" 0020 0021 #include <QObject> 0022 #include <QQmlEngine> 0023 #include <QTest> 0024 0025 // END Includes 0026 0027 // BEGIN TestScriptEnv 0028 0029 TestScriptEnv::TestScriptEnv(KTextEditor::DocumentPrivate *part, bool &cflag) 0030 : m_engine(nullptr) 0031 , m_viewObj(nullptr) 0032 , m_docObj(nullptr) 0033 , m_output(nullptr) 0034 { 0035 m_engine = new QJSEngine(this); 0036 0037 // export read & require function and add the require guard object 0038 QJSValue functions = m_engine->newQObject(new Kate::ScriptHelper(m_engine)); 0039 m_engine->globalObject().setProperty(QStringLiteral("functions"), functions); 0040 m_engine->globalObject().setProperty(QStringLiteral("read"), functions.property(QStringLiteral("read"))); 0041 m_engine->globalObject().setProperty(QStringLiteral("require"), functions.property(QStringLiteral("require"))); 0042 m_engine->globalObject().setProperty(QStringLiteral("require_guard"), m_engine->newObject()); 0043 0044 // export debug function 0045 m_engine->globalObject().setProperty(QStringLiteral("debug"), functions.property(QStringLiteral("debug"))); 0046 0047 // export translation functions 0048 m_engine->globalObject().setProperty(QStringLiteral("i18n"), functions.property(QStringLiteral("_i18n"))); 0049 m_engine->globalObject().setProperty(QStringLiteral("i18nc"), functions.property(QStringLiteral("_i18nc"))); 0050 m_engine->globalObject().setProperty(QStringLiteral("i18np"), functions.property(QStringLiteral("_i18np"))); 0051 m_engine->globalObject().setProperty(QStringLiteral("i18ncp"), functions.property(QStringLiteral("_i18ncp"))); 0052 0053 KTextEditor::ViewPrivate *view = qobject_cast<KTextEditor::ViewPrivate *>(part->widget()); 0054 0055 m_viewObj = new KateViewObject(m_engine, view); 0056 QJSValue sv = m_engine->newQObject(m_viewObj); 0057 0058 m_engine->globalObject().setProperty(QStringLiteral("view"), sv); 0059 m_engine->globalObject().setProperty(QStringLiteral("v"), sv); 0060 0061 m_docObj = new KateDocumentObject(m_engine, view->doc()); 0062 QJSValue sd = m_engine->newQObject(m_docObj); 0063 0064 m_engine->globalObject().setProperty(QStringLiteral("document"), sd); 0065 m_engine->globalObject().setProperty(QStringLiteral("d"), sd); 0066 0067 m_output = new OutputObject(view, cflag); 0068 QJSValue so = m_engine->newQObject(m_output); 0069 0070 m_engine->globalObject().setProperty(QStringLiteral("output"), so); 0071 m_engine->globalObject().setProperty(QStringLiteral("out"), so); 0072 m_engine->globalObject().setProperty(QStringLiteral("o"), so); 0073 } 0074 0075 TestScriptEnv::~TestScriptEnv() 0076 { 0077 // delete explicitly, as the parent is the KTE::Document kpart, which is 0078 // reused for all tests. Hence, we explicitly have to delete the bindings. 0079 delete m_output; 0080 m_output = nullptr; 0081 delete m_docObj; 0082 m_docObj = nullptr; 0083 delete m_viewObj; 0084 m_viewObj = nullptr; 0085 0086 // delete this too, although this should also be automagically be freed 0087 delete m_engine; 0088 m_engine = nullptr; 0089 0090 // kDebug() << "deleted"; 0091 } 0092 // END TestScriptEnv 0093 0094 // BEGIN KateViewObject 0095 0096 KateViewObject::KateViewObject(QJSEngine *engine, KTextEditor::ViewPrivate *view) 0097 : KateScriptView(engine) 0098 { 0099 setView(view); 0100 } 0101 0102 KateViewObject::~KateViewObject() 0103 { 0104 // kDebug() << "deleted"; 0105 } 0106 0107 // Implements a function that calls an edit function repeatedly as specified by 0108 // its first parameter (once if not specified). 0109 #define REP_CALL(func) \ 0110 void KateViewObject::func(int cnt) \ 0111 { \ 0112 while (cnt--) { \ 0113 view()->func(); \ 0114 } \ 0115 } 0116 REP_CALL(keyReturn) 0117 REP_CALL(backspace) 0118 REP_CALL(deleteWordLeft) 0119 REP_CALL(keyDelete) 0120 REP_CALL(deleteWordRight) 0121 REP_CALL(transpose) 0122 REP_CALL(cursorLeft) 0123 REP_CALL(shiftCursorLeft) 0124 REP_CALL(cursorRight) 0125 REP_CALL(shiftCursorRight) 0126 REP_CALL(wordLeft) 0127 REP_CALL(shiftWordLeft) 0128 REP_CALL(wordRight) 0129 REP_CALL(shiftWordRight) 0130 REP_CALL(home) 0131 REP_CALL(shiftHome) 0132 REP_CALL(end) 0133 REP_CALL(shiftEnd) 0134 REP_CALL(up) 0135 REP_CALL(shiftUp) 0136 REP_CALL(down) 0137 REP_CALL(shiftDown) 0138 REP_CALL(scrollUp) 0139 REP_CALL(scrollDown) 0140 REP_CALL(topOfView) 0141 REP_CALL(shiftTopOfView) 0142 REP_CALL(bottomOfView) 0143 REP_CALL(shiftBottomOfView) 0144 REP_CALL(pageUp) 0145 REP_CALL(shiftPageUp) 0146 REP_CALL(pageDown) 0147 REP_CALL(shiftPageDown) 0148 REP_CALL(top) 0149 REP_CALL(shiftTop) 0150 REP_CALL(bottom) 0151 REP_CALL(shiftBottom) 0152 REP_CALL(toMatchingBracket) 0153 REP_CALL(shiftToMatchingBracket) 0154 #undef REP_CALL 0155 0156 void KateViewObject::type(const QString &str) 0157 { 0158 view()->doc()->typeChars(view(), str); 0159 } 0160 0161 void KateViewObject::paste(const QString &str) 0162 { 0163 view()->doc()->paste(view(), str); 0164 } 0165 0166 void KateViewObject::setAutoBrackets(bool enable) 0167 { 0168 view()->config()->setValue(KateViewConfig::AutoBrackets, enable); 0169 } 0170 0171 void KateViewObject::replaceTabs(bool enable) 0172 { 0173 view()->doc()->config()->setValue(KateDocumentConfig::ReplaceTabsWithSpaces, enable); 0174 } 0175 0176 #define ALIAS(alias, func) \ 0177 void KateViewObject::alias(int cnt) \ 0178 { \ 0179 func(cnt); \ 0180 } 0181 ALIAS(enter, keyReturn) 0182 ALIAS(cursorPrev, cursorLeft) 0183 ALIAS(left, cursorLeft) 0184 ALIAS(prev, cursorLeft) 0185 ALIAS(shiftCursorPrev, shiftCursorLeft) 0186 ALIAS(shiftLeft, shiftCursorLeft) 0187 ALIAS(shiftPrev, shiftCursorLeft) 0188 ALIAS(cursorNext, cursorRight) 0189 ALIAS(right, cursorRight) 0190 ALIAS(next, cursorRight) 0191 ALIAS(shiftCursorNext, shiftCursorRight) 0192 ALIAS(shiftRight, shiftCursorRight) 0193 ALIAS(shiftNext, shiftCursorRight) 0194 ALIAS(wordPrev, wordLeft) 0195 ALIAS(shiftWordPrev, shiftWordLeft) 0196 ALIAS(wordNext, wordRight) 0197 ALIAS(shiftWordNext, shiftWordRight) 0198 #undef ALIAS 0199 0200 // END KateViewObject 0201 0202 // BEGIN KateDocumentObject 0203 0204 KateDocumentObject::KateDocumentObject(QJSEngine *engine, KTextEditor::DocumentPrivate *doc) 0205 : KateScriptDocument(engine) 0206 { 0207 setDocument(doc); 0208 } 0209 0210 KateDocumentObject::~KateDocumentObject() 0211 { 0212 // kDebug() << "deleted"; 0213 } 0214 // END KateDocumentObject 0215 0216 // BEGIN OutputObject 0217 OutputObject::OutputObject(KTextEditor::ViewPrivate *v, bool &cflag) 0218 : view(v) 0219 , cflag(cflag) 0220 { 0221 } 0222 0223 OutputObject::~OutputObject() 0224 { 0225 // kDebug() << "deleted"; 0226 } 0227 0228 void OutputObject::output(bool cp, bool ln) 0229 { 0230 QString str; 0231 // FIXME: This is not available with QtQml, but not sure if we need it 0232 // for (int i = 0; i < context()->argumentCount(); ++i) { 0233 // QJSValue arg = context()->argument(i); 0234 // str += arg.toString(); 0235 // } 0236 0237 if (cp) { 0238 KTextEditor::Cursor c = view->cursorPosition(); 0239 str += QLatin1Char('(') + QString::number(c.line()) + QLatin1Char(',') + QString::number(c.column()) + QLatin1Char(')'); 0240 } 0241 0242 if (ln) { 0243 str += QLatin1Char('\n'); 0244 } 0245 0246 view->insertText(str); 0247 0248 cflag = true; 0249 } 0250 0251 void OutputObject::write() 0252 { 0253 output(false, false); 0254 } 0255 0256 void OutputObject::writeln() 0257 { 0258 output(false, true); 0259 } 0260 0261 void OutputObject::writeLn() 0262 { 0263 output(false, true); 0264 } 0265 0266 void OutputObject::print() 0267 { 0268 output(false, false); 0269 } 0270 0271 void OutputObject::println() 0272 { 0273 output(false, true); 0274 } 0275 0276 void OutputObject::printLn() 0277 { 0278 output(false, true); 0279 } 0280 0281 void OutputObject::writeCursorPosition() 0282 { 0283 output(true, false); 0284 } 0285 0286 void OutputObject::writeCursorPositionln() 0287 { 0288 output(true, true); 0289 } 0290 0291 void OutputObject::cursorPosition() 0292 { 0293 output(true, false); 0294 } 0295 0296 void OutputObject::cursorPositionln() 0297 { 0298 output(true, true); 0299 } 0300 0301 void OutputObject::cursorPositionLn() 0302 { 0303 output(true, true); 0304 } 0305 0306 void OutputObject::pos() 0307 { 0308 output(true, false); 0309 } 0310 0311 void OutputObject::posln() 0312 { 0313 output(true, true); 0314 } 0315 0316 void OutputObject::posLn() 0317 { 0318 output(true, true); 0319 } 0320 // END OutputObject 0321 0322 #include "moc_testutils.cpp"