File indexing completed on 2024-05-12 12:35:52
0001 /* This file is part of KDevelop 0002 * 0003 * Copyright (C) 2012-2015 Miquel Sabaté Solà <mikisabate@gmail.com> 0004 * 0005 * This program is free software: you can redistribute it and/or modify 0006 * it under the terms of the GNU General Public License as published by 0007 * the Free Software Foundation, either version 3 of the License, or 0008 * (at your option) any later version. 0009 * 0010 * This program is distributed in the hope that it will be useful, 0011 * but WITHOUT ANY WARRANTY; without even the implied warranty of 0012 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 0013 * GNU General Public License for more details. 0014 * 0015 * You should have received a copy of the GNU General Public License 0016 * along with this program. If not, see <http://www.gnu.org/licenses/>. 0017 */ 0018 0019 0020 #include <QtTest/QtTest> 0021 #include <completion/tests/completion.h> 0022 #include <completion/context.h> 0023 #include <language/codecompletion/codecompletiontesthelper.h> 0024 0025 0026 QTEST_MAIN(ruby::TestCompletion) 0027 0028 using namespace KDevelop; 0029 namespace ruby 0030 { 0031 0032 //BEGIN: Helper structures 0033 using BaseRubyCompletionTester = 0034 CodeCompletionItemTester<CodeCompletionContext>; 0035 0036 class RubyCompletionTester : public BaseRubyCompletionTester 0037 { 0038 public: 0039 RubyCompletionTester(DUContext *context, QString text = "; ", QString followingText = "", 0040 CursorInRevision position = CursorInRevision::invalid()) 0041 : BaseRubyCompletionTester(context, text, followingText, position) 0042 { 0043 /* There's nothing to do here */ 0044 } 0045 }; 0046 0047 const QByteArray testBase( 0048 "class Base\n" 0049 " def somewhere; end\n" 0050 " def over; end\n" 0051 " protected\n" 0052 " def the; end\n" 0053 " private\n" 0054 " def rainbow; end\n" 0055 "end\n" 0056 ); 0057 0058 const QByteArray testKlass( 0059 "class Klass < Base\n" 0060 "end\n" 0061 ); 0062 //END: Helper structures 0063 0064 TestCompletion::TestCompletion() 0065 { 0066 /* There's nothing to do here */ 0067 } 0068 0069 KDevelop::TopDUContext * TestCompletion::parse(const QByteArray &code, const QString &id) 0070 { 0071 const QString &name = "completion_" + id; 0072 return DUChainTestBase::parse(code, name); 0073 } 0074 0075 void TestCompletion::shouldContain(const QStringList &list, const QStringList &shoulda, bool sameSize) 0076 { 0077 if (sameSize) 0078 QCOMPARE(list.size(), shoulda.size()); 0079 foreach (const QString &str, shoulda) 0080 QVERIFY(list.contains(str, Qt::CaseSensitive)); 0081 } 0082 0083 void TestCompletion::standardAccess() 0084 { 0085 QByteArray code("obj = 1; "); 0086 TopDUContext *top = parse(code, "standardAccess"); 0087 DUChainReleaser releaseTop(top); 0088 DUChainWriteLocker lock; 0089 0090 { 0091 RubyCompletionTester tester(top, ""); 0092 shouldContain(tester.names, QStringList() << "obj" << "Kernel" << "while"); 0093 } 0094 } 0095 0096 void TestCompletion::baseClass() 0097 { 0098 QByteArray code("class BaseClass; end;"); 0099 TopDUContext *top = parse(code, "baseClass"); 0100 DUChainReleaser releaseTop(top); 0101 DUChainWriteLocker lock; 0102 0103 { 0104 RubyCompletionTester tester(top, "class Klass < "); 0105 shouldContain(tester.names, QStringList() << "BaseClass" << "Object" << "String"); 0106 } 0107 } 0108 0109 void TestCompletion::moduleMixins() 0110 { 0111 QByteArray code("module Awesome; end; "); 0112 TopDUContext *top = parse(code, "moduleMixins"); 0113 DUChainReleaser releaseTop(top); 0114 DUChainWriteLocker lock; 0115 0116 { 0117 RubyCompletionTester tester(top, "module MyModule; include "); 0118 shouldContain(tester.names, QStringList() << "Awesome" << "Kernel" << "Enumerable"); 0119 } 0120 0121 { 0122 RubyCompletionTester tester(top, "module MyModule; extend "); 0123 shouldContain(tester.names, QStringList() << "Awesome" << "Kernel" << "Enumerable"); 0124 } 0125 } 0126 0127 void TestCompletion::memberAccess() 0128 { 0129 QByteArray code(testBase); 0130 TopDUContext *top = parse(code, "memberAccess"); 0131 DUChainReleaser releaseTop(top); 0132 DUChainWriteLocker lock; 0133 0134 { 0135 RubyCompletionTester tester(top, "obj = Base.new; obj."); 0136 shouldContain(tester.names, QStringList() << "somewhere" << "over", true); 0137 } 0138 } 0139 0140 void TestCompletion::checkSubclassing() 0141 { 0142 QByteArray code(testBase + testKlass); 0143 TopDUContext *top = parse(code, "checkSubclassing"); 0144 DUChainReleaser releaseTop(top); 0145 DUChainWriteLocker lock; 0146 0147 { 0148 RubyCompletionTester tester(top, testBase + testKlass + "obj = Klass.new; obj."); 0149 shouldContain(tester.names, QStringList() << "somewhere" << "over", true); 0150 } 0151 } 0152 0153 void TestCompletion::classMemberAccess() 0154 { 0155 // TODO: I think that the text should not be in here anymore... 0156 QByteArray code("module MyModule; class Klass; end; end\n"); 0157 TopDUContext *top = parse(code, "classMemberAccess"); 0158 DUChainReleaser releaseTop(top); 0159 DUChainWriteLocker lock; 0160 0161 { 0162 RubyCompletionTester tester(top, "module MyModule; class Klass; end; end\nMyModule::"); 0163 shouldContain(tester.names, QStringList() << "Klass", true); 0164 } 0165 } 0166 0167 void TestCompletion::fileChoose() 0168 { 0169 QByteArray code("a = 0\n"); 0170 TopDUContext *top = parse(code, "fileChoose"); 0171 DUChainReleaser releaseTop(top); 0172 DUChainWriteLocker lock; 0173 0174 { 0175 // Using the stdlib. It's ok if you've installed ruby 1.8.x or 1.9.x 0176 RubyCompletionTester tester(top, "require 'rss/"); 0177 shouldContain(tester.names, QStringList() << "maker/" << "0.9.rb" << "utils.rb"); 0178 } 0179 0180 { 0181 // The name used to check if it works is the file containing this same test. 0182 RubyCompletionTester tester(top, "require_relative '"); 0183 shouldContain(tester.names, QStringList() << "kdevruby_completion_fileChoose.rb"); 0184 } 0185 } 0186 0187 } 0188