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 extends VFileEvent> 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 extends VFileEvent> 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 extends VFileEvent> events) {
}
}
// fixme debug only
- DCLogger.info("MyBulkFileListener.after ends");
+ DCLogger.info("MyBulkFileListener.after ends for: " + events);
}
@Override
public void before(@NotNull List extends VFileEvent> 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 extends VFileEvent> 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