diff --git a/DeveloperGuide.md b/DeveloperGuide.md index e99a66a..c51ce3d 100644 --- a/DeveloperGuide.md +++ b/DeveloperGuide.md @@ -6,9 +6,14 @@ - Check if java is correctly installed (and your java version) with `java -version` command; - Place `java-client-{X.X.X}-all.jar` into `..\libs` dir (see [java-client](https://github.com/DeepCodeAI/java-client) repository for instruction how to build it); - At `build.gradle` file inside `intellij` block: uncomment `version` line and comment `localPath` line (or change `localPath` to pointing your locally installed Intellij Idea `2019.2` version instance); +**Important note: For backward compatibility build MUST be run against Intellij Idea 2019.2 instance!** - Run `source gradlew buildPlugin` - Look for resulting ZIP file at `..\build\distributions` +### Run tests + +- Run gradle test task: `source gradlew test --stacktrace --scan` + ### Useful links - IntelliJ Platform SDK [documentation](https://www.jetbrains.org/intellij/sdk/docs/intro/welcome.html) - JetBrains Marketplace [documentation](https://plugins.jetbrains.com/docs/marketplace/about-marketplace.html) diff --git a/build.gradle b/build.gradle index 6e6e226..65c937f 100644 --- a/build.gradle +++ b/build.gradle @@ -7,7 +7,7 @@ plugins { //group 'org.example' -version '1.0.1' +version '1.0.2' sourceCompatibility = 1.8 repositories { @@ -27,8 +27,7 @@ intellij { // localPath '/Users/arvid/Library/Application Support/JetBrains/Toolbox/apps/IDEA-C/ch-0/201.7223.91/IntelliJ IDEA CE.app/Contents' // localPath 'C:\\Users\\artem\\AppData\\Local\\JetBrains\\Toolbox\\apps\\PyCharm-C\\ch-0\\193.5233.109' // plugins += 'java' -// plugins += 'PsiViewer:201-SNAPSHOT' - plugins += 'PsiViewer:192-SNAPSHOT' +// plugins += 'PsiViewer:192-SNAPSHOT' } patchPluginXml { @@ -91,7 +90,14 @@ task run_PC_193(type: RunIdeTask){ task run_AS_40(type: RunIdeTask){ jvmArgs '-Xmx2G' + jbrVersion '8u202b1483.24' ideDirectory 'C:\\Users\\artem\\AppData\\Local\\JetBrains\\Toolbox\\apps\\AndroidStudio\\ch-0\\193.6453388' } +task run_AS_36(type: RunIdeTask){ + jvmArgs '-Xmx2G' + jbrVersion '8u202b1483.24' + ideDirectory 'C:\\Users\\artem\\AppData\\Local\\JetBrains\\Toolbox\\apps\\AndroidStudio\\ch-1\\192.6392135' +} + tasks.withType(RunIdeTask).forEach {task -> task.dependsOn(prepareSandbox)} diff --git a/src/main/java/ai/deepcode/jbplugin/DeepCodeNotifications.java b/src/main/java/ai/deepcode/jbplugin/DeepCodeNotifications.java index 286ed31..e3ff850 100644 --- a/src/main/java/ai/deepcode/jbplugin/DeepCodeNotifications.java +++ b/src/main/java/ai/deepcode/jbplugin/DeepCodeNotifications.java @@ -47,7 +47,7 @@ public static void showLoginLink(@Nullable Project project, @NotNull String mess new Notification(groupNeedAction, title, message, NotificationType.WARNING) .addAction( new ShowClickableLinkAction( - "Login", () -> LoginUtils.requestNewLogin(prj), true)); + "Login", () -> LoginUtils.requestNewLogin(prj, true), true)); lastNotifications.add(notification); notification.notify(prj); } @@ -58,10 +58,8 @@ public static void showLoginLink(@Nullable Project project, @NotNull String mess public static void showConsentRequest(@NotNull Project project, boolean userActionNeeded) { if (!userActionNeeded && consentRequestShown) return; lastNotificationRunnable = () -> showConsentRequest(project, userActionNeeded); - final String message = - "Confirm remote analysis of " - + project.getBasePath(); -// + " (Terms & Conditions)"; + final String message = "Confirm remote analysis of " + project.getBasePath(); + // + " (Terms & Conditions)"; final Notification notification = new ConsentNotification( groupNeedAction, @@ -109,7 +107,7 @@ public void actionPerformed(@NotNull AnActionEvent e) { } } - private static void expireNotification(@NotNull Notification notification){ + private static void expireNotification(@NotNull Notification notification) { if (notification instanceof ConsentNotification) { ((ConsentNotification) notification).consentExpired(); } else { diff --git a/src/main/java/ai/deepcode/jbplugin/actions/SeeResultsInBrowserAction.java b/src/main/java/ai/deepcode/jbplugin/actions/SeeResultsInBrowserAction.java index 88a9392..6b53ff5 100644 --- a/src/main/java/ai/deepcode/jbplugin/actions/SeeResultsInBrowserAction.java +++ b/src/main/java/ai/deepcode/jbplugin/actions/SeeResultsInBrowserAction.java @@ -4,18 +4,24 @@ import com.intellij.ide.BrowserUtil; import com.intellij.openapi.actionSystem.AnAction; import com.intellij.openapi.actionSystem.AnActionEvent; +import com.intellij.openapi.project.Project; import org.jetbrains.annotations.NotNull; public class SeeResultsInBrowserAction extends AnAction { @Override public void update(@NotNull AnActionEvent e) { - e.getPresentation().setEnabled(!AnalysisData.getAnalysisUrl().isEmpty()); + final Project project = e.getProject(); + if (project==null) return; + final boolean urlExist = !AnalysisData.getAnalysisUrl(project).isEmpty(); + e.getPresentation().setEnabled(urlExist); } @Override public void actionPerformed(@NotNull AnActionEvent e) { - final String analysisUrl = AnalysisData.getAnalysisUrl(); + final Project project = e.getProject(); + if (project==null) return; + final String analysisUrl = AnalysisData.getAnalysisUrl(project); if (!analysisUrl.isEmpty()) BrowserUtil.open(analysisUrl); } } diff --git a/src/main/java/ai/deepcode/jbplugin/core/AnalysisData.java b/src/main/java/ai/deepcode/jbplugin/core/AnalysisData.java index f1d97e2..6428d3e 100644 --- a/src/main/java/ai/deepcode/jbplugin/core/AnalysisData.java +++ b/src/main/java/ai/deepcode/jbplugin/core/AnalysisData.java @@ -42,7 +42,7 @@ private AnalysisData() {} private static final Logger LOG = LoggerFactory.getLogger("DeepCode.AnalysisData"); private static final Map> EMPTY_MAP = Collections.emptyMap(); - private static String analysisUrl = ""; + private static Map mapProject2analysisUrl = new ConcurrentHashMap<>(); // todo: keep few latest file versions (Guava com.google.common.cache.CacheBuilder ?) private static final Map> mapFile2Suggestions = @@ -94,8 +94,8 @@ public static Map> getAnalysis( return result; } - public static String getAnalysisUrl() { - return analysisUrl; + public static String getAnalysisUrl(@NotNull Project project) { + return mapProject2analysisUrl.computeIfAbsent(project, p -> ""); } static boolean addProjectToCache(@NotNull Project project) { @@ -184,11 +184,17 @@ public static void updateCachedResultsForFiles( .filter(file -> !mapFile2Suggestions.containsKey(file)) .collect(Collectors.toSet()); if (!filesToProceed.isEmpty()) { - info("Files to proceed (not found in cache): " + filesToProceed.size()); - // fixme debug only // deepcode ignore checkIsPresent~Optional: collection already checked to be not empty final PsiFile firstFile = filesToProceed.stream().findFirst().get(); - info("Hash for first file " + firstFile.getName() + " [" + getHash(firstFile) + "]"); + info( + "Files to proceed (not found in cache): " + + filesToProceed.size() + // fixme debug only + + "\nHash for first file " + + firstFile.getName() + + " [" + + getHash(firstFile) + + "]"); mapFile2Suggestions.putAll(retrieveSuggestions(project, filesToProceed, filesToRemove)); @@ -251,10 +257,6 @@ private static Map> retrieveSuggestions( info(PREPARE_FILES_TEXT); ProgressManager.checkCanceled(); mapPsiFile2Content.clear(); - List removedFiles = - filesToRemove.stream() - .map(DeepCodeUtils::getDeepCodedFilePath) - .collect(Collectors.toList()); Map mapPath2Hash = new HashMap<>(); long sizePath2Hash = 0; int fileCounter = 0; @@ -280,7 +282,7 @@ private static Map> retrieveSuggestions( } } // todo break removeFiles in chunks less then MAX_BANDLE_SIZE - CreateBundleResponse createBundleResponse = makeNewBundle(project, mapPath2Hash, removedFiles); + CreateBundleResponse createBundleResponse = makeNewBundle(project, mapPath2Hash, filesToRemove); if (isNotSucceed(project, createBundleResponse, "Bad Create/Extend Bundle request: ")) return EMPTY_MAP; info( @@ -353,7 +355,7 @@ private static Map> retrieveSuggestions( progress.setText(WAITING_FOR_ANALYSIS_TEXT); ProgressManager.checkCanceled(); GetAnalysisResponse getAnalysisResponse = doRetrieveSuggestions(project, bundleId, progress); - result = parseGetAnalysisResponse(psiFiles, getAnalysisResponse, progress); + result = parseGetAnalysisResponse(project, psiFiles, getAnalysisResponse, progress); info("--- Get Analysis took: " + (System.currentTimeMillis() - startTime) + " milliseconds"); // progress.stop(); return result; @@ -362,9 +364,21 @@ private static Map> retrieveSuggestions( private static CreateBundleResponse makeNewBundle( @NotNull Project project, @NotNull Map mapPath2Hash, - @NotNull List removedFiles) { + @NotNull Collection filesToRemove) { final FileHashRequest fileHashRequest = new FileHashRequest(mapPath2Hash); final String parentBundleId = mapProject2BundleId.getOrDefault(project, ""); + if (!parentBundleId.isEmpty() + && !filesToRemove.isEmpty() + && mapPath2Hash.isEmpty() + && filesToRemove.containsAll(cachedFilesOfProject(project))) { + warn( + "Attempt to Extending a bundle by removing all the parent bundle's files: " + + filesToRemove); + } + List removedFiles = + filesToRemove.stream() + .map(DeepCodeUtils::getDeepCodedFilePath) + .collect(Collectors.toList()); String message = (parentBundleId.isEmpty() ? "Creating new Bundle with " @@ -385,10 +399,19 @@ private static CreateBundleResponse makeNewBundle( parentBundleId, new ExtendBundleRequest(fileHashRequest.getFiles(), removedFiles)); } - mapProject2BundleId.put(project, bundleResponse.getBundleId()); + String newBundleId = bundleResponse.getBundleId(); + // By man: "Extending a bundle by removing all the parent bundle's files is not allowed." + // In reality new bundle returned with next bundleID: + // gh/ArtsiomCh/DEEPCODE_PRIVATE_BUNDLE/0000000000000000000000000000000000000000000000000000000000000000 + if (newBundleId.equals( + "gh/ArtsiomCh/DEEPCODE_PRIVATE_BUNDLE/0000000000000000000000000000000000000000000000000000000000000000")) { + newBundleId = ""; + } + mapProject2BundleId.put(project, newBundleId); return bundleResponse; } + // ?? com.intellij.openapi.util.text.StringUtil.toHexString // https://www.baeldung.com/sha-256-hashing-java#message-digest private static String bytesToHex(byte[] hash) { StringBuilder hexString = new StringBuilder(); @@ -512,13 +535,14 @@ private static GetAnalysisResponse doRetrieveSuggestions( @NotNull private static Map> parseGetAnalysisResponse( + @NotNull Project project, @NotNull Collection psiFiles, GetAnalysisResponse response, @NotNull ProgressIndicator progressIndicator) { Map> result = new HashMap<>(); if (!response.getStatus().equals("DONE")) return EMPTY_MAP; AnalysisResults analysisResults = response.getAnalysisResults(); - analysisUrl = response.getAnalysisURL(); + mapProject2analysisUrl.put(project, response.getAnalysisURL()); if (analysisResults == null) { LOG.error("AnalysisResults is null for: {}", response); return EMPTY_MAP; @@ -603,7 +627,7 @@ public static void clearCache(@Nullable final Project project) { for (Project prj : projects) { removeProjectFromCache(prj); ServiceManager.getService(prj, myTodoView.class).refresh(); + mapProject2analysisUrl.put(prj, ""); } - analysisUrl = ""; } } diff --git a/src/main/java/ai/deepcode/jbplugin/core/LoginUtils.java b/src/main/java/ai/deepcode/jbplugin/core/LoginUtils.java index 0e96de8..825b647 100644 --- a/src/main/java/ai/deepcode/jbplugin/core/LoginUtils.java +++ b/src/main/java/ai/deepcode/jbplugin/core/LoginUtils.java @@ -18,7 +18,7 @@ public class LoginUtils { private LoginUtils() {} private static final String userAgent = - "JetBrains-plugin-" + "JetBrains-" + ApplicationNamesInfo.getInstance().getProductName() + "-" + ApplicationInfo.getInstance().getFullVersion(); @@ -54,15 +54,17 @@ public static boolean isLogged(@Nullable Project project, boolean userActionNeed } /** network request! */ - public static void requestNewLogin(@NotNull Project project) { + public static void requestNewLogin(@NotNull Project project, boolean openBrowser) { DCLogger.info("New Login requested."); DeepCodeParams.clearLoginParams(); LoginResponse response = DeepCodeRestApi.newLogin(userAgent); if (response.getStatusCode() == 200) { - DCLogger.info("New Login request succeed. New Token: " + response.getSessionToken()); + DCLogger.info("New Login request succeed. New Token: " + response.getSessionToken()); DeepCodeParams.setSessionToken(response.getSessionToken()); DeepCodeParams.setLoginUrl(response.getLoginURL()); - BrowserUtil.open(DeepCodeParams.getLoginUrl()); + if (openBrowser) { + BrowserUtil.open(DeepCodeParams.getLoginUrl()); + } if (!isLoginCheckLoopStarted) { ReadAction.nonBlocking(() -> startLoginCheckLoop(project)) .submit(NonUrgentExecutor.getInstance()); diff --git a/src/main/java/ai/deepcode/jbplugin/core/MyBulkFileListener.java b/src/main/java/ai/deepcode/jbplugin/core/MyBulkFileListener.java index 1f98bd0..cf8bb58 100644 --- a/src/main/java/ai/deepcode/jbplugin/core/MyBulkFileListener.java +++ b/src/main/java/ai/deepcode/jbplugin/core/MyBulkFileListener.java @@ -26,7 +26,7 @@ public class MyBulkFileListener implements BulkFileListener { @Override public void after(@NotNull List events) { // fixme debug only - DCLogger.info("MyBulkFileListener.after begins"); + DCLogger.info("MyBulkFileListener.after begins for: " + events); for (Project project : AnalysisData.getAllCachedProject()) { RunUtils.runInBackground( project, @@ -48,11 +48,16 @@ public void after(@NotNull List events) { // fixme doen't work for copy-past file ( VFileMoveEvent ?) VFileCreateEvent.class)); if (!filesChangedOrCreated.isEmpty()) { - // fixme debug only DCLogger.info( filesChangedOrCreated.size() + " files changed: " + filesChangedOrCreated); - AnalysisData.removeFilesFromCache(filesChangedOrCreated); - RunUtils.asyncAnalyseAndUpdatePanel(project, filesChangedOrCreated); + for (PsiFile psiFile : filesChangedOrCreated) { + RunUtils.runInBackgroundCancellable( + psiFile, + () -> { + AnalysisData.removeFilesFromCache(Collections.singleton(psiFile)); + RunUtils.asyncAnalyseAndUpdatePanel(project, Collections.singleton(psiFile)); + }); + } } }); @@ -74,12 +79,12 @@ public void after(@NotNull List events) { } } // fixme debug only - DCLogger.info("MyBulkFileListener.after ends"); + DCLogger.info("MyBulkFileListener.after ends for: " + events); } @Override public void before(@NotNull List events) { - DCLogger.info("MyBulkFileListener.before begins"); + DCLogger.info("MyBulkFileListener.before begins for: " + events); for (Project project : AnalysisData.getAllCachedProject()) { if (project.isDisposed()) continue; Set filesRemoved = @@ -107,7 +112,7 @@ public void before(@NotNull List events) { }); } } - DCLogger.info("MyBulkFileListener.before ends"); + DCLogger.info("MyBulkFileListener.before ends for: " + events); } private Set getFilteredFilesByEventTypes( diff --git a/src/test/.dcignore b/src/test/.dcignore new file mode 100644 index 0000000..204d175 --- /dev/null +++ b/src/test/.dcignore @@ -0,0 +1 @@ +testData \ No newline at end of file diff --git a/src/test/java/ai/deepcode/jbplugin/MyBasePlatformTestCase.java b/src/test/java/ai/deepcode/jbplugin/MyBasePlatformTestCase.java new file mode 100644 index 0000000..5db6e5b --- /dev/null +++ b/src/test/java/ai/deepcode/jbplugin/MyBasePlatformTestCase.java @@ -0,0 +1,28 @@ +package ai.deepcode.jbplugin; + +import ai.deepcode.jbplugin.core.DeepCodeParams; +import com.intellij.openapi.project.Project; +import com.intellij.testFramework.fixtures.BasePlatformTestCase; + +/** + * See: https://www.jetbrains.org/intellij/sdk/docs/basics/testing_plugins/testing_plugins.html See: + * https://www.jetbrains.org/intellij/sdk/docs/tutorials/writing_tests_for_plugins.html + */ +public abstract class MyBasePlatformTestCase extends BasePlatformTestCase { + protected Project project; + + @Override + protected void setUp() throws Exception { + super.setUp(); + project = myFixture.getProject(); + } + + // !!! Will works only with already logged sessionToken + protected static final String loggedToken = + "aeedc7d1c2656ea4b0adb1e215999f588b457cedf415c832a0209c9429c7636e"; + + @Override + protected String getTestDataPath() { + return "src/test/testData"; + } +} diff --git a/src/test/java/ai/deepcode/jbplugin/MyPlatformTestCase.java b/src/test/java/ai/deepcode/jbplugin/MyPlatformTestCase.java new file mode 100644 index 0000000..ff329a0 --- /dev/null +++ b/src/test/java/ai/deepcode/jbplugin/MyPlatformTestCase.java @@ -0,0 +1,15 @@ +package ai.deepcode.jbplugin; + +import com.intellij.testFramework.PlatformTestCase; + +/** + * See: https://www.jetbrains.org/intellij/sdk/docs/basics/testing_plugins/testing_plugins.html See: + * https://www.jetbrains.org/intellij/sdk/docs/tutorials/writing_tests_for_plugins.html + */ +public abstract class MyPlatformTestCase extends PlatformTestCase { + + // !!! Will works only with already logged sessionToken + protected static final String loggedToken = + "aeedc7d1c2656ea4b0adb1e215999f588b457cedf415c832a0209c9429c7636e"; + +} diff --git a/src/test/java/ai/deepcode/jbplugin/TestAnnotatorForCPP.java b/src/test/java/ai/deepcode/jbplugin/TestAnnotatorForCPP.java new file mode 100644 index 0000000..ac92d25 --- /dev/null +++ b/src/test/java/ai/deepcode/jbplugin/TestAnnotatorForCPP.java @@ -0,0 +1,17 @@ +package ai.deepcode.jbplugin; + +import ai.deepcode.jbplugin.core.DeepCodeParams; +import ai.deepcode.jbplugin.core.RunUtils; + +public class TestAnnotatorForCPP extends MyBasePlatformTestCase { + + public void testHighlighting_CPP() { + DeepCodeParams.setSessionToken(loggedToken); + DeepCodeParams.setConsentGiven(project); + myFixture.configureByFile("AnnotatorTest.cpp"); + //fixme: delay to let annotators do the job + RunUtils.delay(2000); + myFixture.checkHighlighting(true, true, true, false); + } + +} diff --git a/src/test/java/ai/deepcode/jbplugin/TestAnnotatorForJava.java b/src/test/java/ai/deepcode/jbplugin/TestAnnotatorForJava.java new file mode 100644 index 0000000..65320c6 --- /dev/null +++ b/src/test/java/ai/deepcode/jbplugin/TestAnnotatorForJava.java @@ -0,0 +1,17 @@ +package ai.deepcode.jbplugin; + +import ai.deepcode.jbplugin.core.DeepCodeParams; +import ai.deepcode.jbplugin.core.RunUtils; + +public class TestAnnotatorForJava extends MyBasePlatformTestCase { + + public void testHighlighting_Java() { + DeepCodeParams.setSessionToken(loggedToken); + DeepCodeParams.setConsentGiven(project); + myFixture.configureByFile("AnnotatorTest.java"); + //fixme: delay to let annotators do the job + RunUtils.delay(2000); + myFixture.checkHighlighting(true, true, true, true); + } + +} diff --git a/src/test/java/ai/deepcode/jbplugin/TestAnnotatorForJavaScript.java b/src/test/java/ai/deepcode/jbplugin/TestAnnotatorForJavaScript.java new file mode 100644 index 0000000..c27fcd9 --- /dev/null +++ b/src/test/java/ai/deepcode/jbplugin/TestAnnotatorForJavaScript.java @@ -0,0 +1,14 @@ +package ai.deepcode.jbplugin; + +import ai.deepcode.jbplugin.core.DeepCodeParams; + +public class TestAnnotatorForJavaScript extends MyBasePlatformTestCase { + + public void testHighlighting_JavaScript() { + DeepCodeParams.setSessionToken(loggedToken); + DeepCodeParams.setConsentGiven(project); + myFixture.configureByFile("AnnotatorTest.js"); + myFixture.checkHighlighting(true, true, true, false); + } + +} diff --git a/src/test/java/ai/deepcode/jbplugin/TestLoginProcess.java b/src/test/java/ai/deepcode/jbplugin/TestLoginProcess.java new file mode 100644 index 0000000..58a2908 --- /dev/null +++ b/src/test/java/ai/deepcode/jbplugin/TestLoginProcess.java @@ -0,0 +1,34 @@ +package ai.deepcode.jbplugin; + +import ai.deepcode.jbplugin.core.DeepCodeParams; +import ai.deepcode.jbplugin.core.LoginUtils; +import com.intellij.ide.util.PropertiesComponent; + +public class TestLoginProcess extends MyBasePlatformTestCase { + + public void testMalformedToken() { + DeepCodeParams.setSessionToken("blablabla"); + assertFalse("Login with malformed Token should fail", LoginUtils.isLogged(project, false)); + } + + public void testNotLoggedToken() { + LoginUtils.requestNewLogin(project, false); + assertFalse( + "Login with newly requested but not yet logged token should fail", + LoginUtils.isLogged(project, false)); + } + + public void testNotGivenConsent() { + DeepCodeParams.setSessionToken(loggedToken); + PropertiesComponent.getInstance(project).setValue("consentGiven", false); + assertFalse("Login without Consent should fail", LoginUtils.isLogged(project, false)); + } + + public void testLoggedTokenAndGivenConsent() { + DeepCodeParams.setSessionToken(loggedToken); + DeepCodeParams.setConsentGiven(project); + assertTrue( + "Login with logged Token and confirmed Consent should pass", + LoginUtils.isLogged(project, false)); + } +} diff --git a/src/test/java/ai/deepcode/jbplugin/core/TestInnerCaches.java b/src/test/java/ai/deepcode/jbplugin/core/TestInnerCaches.java new file mode 100644 index 0000000..fa9d8c6 --- /dev/null +++ b/src/test/java/ai/deepcode/jbplugin/core/TestInnerCaches.java @@ -0,0 +1,48 @@ +package ai.deepcode.jbplugin.core; + +import ai.deepcode.jbplugin.MyBasePlatformTestCase; +import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiFile; + +import java.util.Collections; +import java.util.Set; + +import static ai.deepcode.jbplugin.core.RunUtils.runInBackground; + +public class TestInnerCaches extends MyBasePlatformTestCase { + PsiFile psiTestFile; + + @Override + protected void setUp() throws Exception { + super.setUp(); + DeepCodeParams.setSessionToken(loggedToken); + DeepCodeParams.setConsentGiven(project); + + myFixture.configureByFile("AnnotatorTest_ValidJS.js"); + psiTestFile = myFixture.getFile(); + + runInBackground( + project, + () -> + AnalysisData.updateCachedResultsForFiles( + project, Collections.singleton(psiTestFile), Collections.emptyList())); + + AnalysisData.waitForUpdateAnalysisFinish(); + //RunUtils.delay(1000); + } + + public void testProjectInCache() { + final Set allCachedProject = AnalysisData.getAllCachedProject(); + assertTrue( + "Current Project should be in cache.", + allCachedProject.size() == 1 && allCachedProject.contains(project)); + } + + public void testFileInCache() { + assertTrue("Test file is not in cache", AnalysisData.isFileInCache(psiTestFile)); + + final Set filesWithSuggestions = AnalysisData.getAllFilesWithSuggestions(project); + assertFalse("List of Files with suggestions is empty", filesWithSuggestions.isEmpty()); + assertTrue("Test file has no suggestions in cache", filesWithSuggestions.contains(psiTestFile)); + } +} diff --git a/src/test/resources/log4j.properties b/src/test/resources/log4j.properties new file mode 100644 index 0000000..393e087 --- /dev/null +++ b/src/test/resources/log4j.properties @@ -0,0 +1,8 @@ +# Root logger option +log4j.rootLogger=INFO, stdout + +# Direct log messages to stdout +log4j.appender.stdout=org.apache.log4j.ConsoleAppender +log4j.appender.stdout.Target=System.out +log4j.appender.stdout.layout=org.apache.log4j.PatternLayout +log4j.appender.stdout.layout.ConversionPattern=%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n \ No newline at end of file diff --git a/src/test/testData/AnnotatorTest.cpp b/src/test/testData/AnnotatorTest.cpp new file mode 100644 index 0000000..80d80e5 --- /dev/null +++ b/src/test/testData/AnnotatorTest.cpp @@ -0,0 +1,4 @@ +int main() { + ReffedClientGraph* to_unref = nullptr; + if (to_unref != nullptr) {} +} diff --git a/src/test/testData/AnnotatorTest.java b/src/test/testData/AnnotatorTest.java new file mode 100644 index 0000000..2a27d96 --- /dev/null +++ b/src/test/testData/AnnotatorTest.java @@ -0,0 +1,9 @@ +public class AnnotatorTest { + public static void delay(long millis) { + try { + Thread.sleep(millis); + } catch (InterruptedException e) { + e.printStackTrace(); + } + } +} diff --git a/src/test/testData/AnnotatorTest.js b/src/test/testData/AnnotatorTest.js new file mode 100644 index 0000000..d7bdbed --- /dev/null +++ b/src/test/testData/AnnotatorTest.js @@ -0,0 +1,5 @@ +(function($) { + + var todo = storage.getTODOs(pullRequestJson).filter(function(todo) {}); + +}(AJS.$)); \ No newline at end of file diff --git a/src/test/testData/AnnotatorTest_ValidJS.js b/src/test/testData/AnnotatorTest_ValidJS.js new file mode 100644 index 0000000..c6b9298 --- /dev/null +++ b/src/test/testData/AnnotatorTest_ValidJS.js @@ -0,0 +1,5 @@ +(function($) { + + var todo = storage.getTODOs(pullRequestJson).filter(function(todo) {}); + +}(AJS.$)); \ No newline at end of file