<commit_before>package org.jetbrains.plugins.scala.lang.completion3

import com.intellij.codeInsight.completion.CompletionType
import com.intellij.codeInsight.completion.CompletionType.BASIC
import com.intellij.codeInsight.lookup.LookupElement
import com.intellij.psi.{PsiMember, PsiNamedElement, PsiPackage}
import org.jetbrains.plugins.scala.extensions.PsiMemberExt
import org.jetbrains.plugins.scala.lang.psi.impl.toplevel.synthetic.SyntheticNamedElement
import org.jetbrains.plugins.scala.lang.resolve.ResolveUtils
import org.junit.Assert

class ScalaCompletionScopeTest extends ScalaCodeInsightTestBase {

  private def checkCompletionsAreInScopeAndAccessible(prefix: String, completionType: CompletionType, times: Int): Unit = {
    val scope = getModule.getModuleWithDependenciesAndLibrariesScope(/*includeTests*/ true)
    configureTest(
      s"""
         |object A {
         |  $prefix$CARET
         |}""".stripMargin,
      completionType,
      times
    )

    val checkAccessibility = times <= 1

    val place = activeLookup.map(_.getPsiElement).orNull
    val allLookups = lookups(isValid)
    allLookups.foreach { lookup =>
      val psiElement = lookup.getPsiElement
      val vFile = psiElement.getContainingFile.getVirtualFile
      Assert.assertTrue(s"Module scope doesn't contain element from ${vFile.getCanonicalPath}", scope.contains(vFile))

      if (checkAccessibility) {
        psiElement match {
          case m: PsiMember =>
            val qName = m.qualifiedNameOpt.getOrElse(m.getName)
            Assert.assertTrue(s"$qName is not accessible", ResolveUtils.isAccessible(m, place, forCompletion = true))
        }
      }
    }
  }

  private def isValid(lookup: LookupElement): Boolean = {
    lookup.getPsiElement match {
      case _: SyntheticNamedElement => false
      case _: PsiPackage            => false
      case _: PsiNamedElement       => true
      case _                        => false
    }
  }

  def testBasicCompletion0(): Unit = checkCompletionsAreInScopeAndAccessible("File", BASIC, 0)
  def testBasicCompletion1(): Unit = checkCompletionsAreInScopeAndAccessible("File", BASIC, 1)
  def testBasicCompletion2(): Unit = checkCompletionsAreInScopeAndAccessible("File", BASIC, 2)

  def testBasicCompletion1EmptyPrefix(): Unit = checkCompletionsAreInScopeAndAccessible("", BASIC, 1)
}<commit_msg>more tests for completion scope #SCL-15521<commit_after>package org.jetbrains.plugins.scala.lang.completion3

import com.intellij.codeInsight.completion.CompletionType
import com.intellij.codeInsight.completion.CompletionType.BASIC
import com.intellij.codeInsight.lookup.LookupElement
import com.intellij.psi.{PsiMember, PsiNamedElement, PsiPackage}
import org.jetbrains.plugins.scala.extensions.PsiMemberExt
import org.jetbrains.plugins.scala.lang.psi.impl.toplevel.synthetic.SyntheticNamedElement
import org.jetbrains.plugins.scala.lang.resolve.ResolveUtils
import org.junit.Assert

class ScalaCompletionScopeTest extends ScalaCodeInsightTestBase {

  private def checkCompletionsAreInScopeAndAccessible(prefix: String, completionType: CompletionType, times: Int): Unit = {
    val scope = getModule.getModuleWithDependenciesAndLibrariesScope(/*includeTests*/ true)
    configureTest(
      s"""
         |object A {
         |  $prefix$CARET
         |}""".stripMargin,
      completionType,
      times
    )

    val checkAccessibility = times <= 1

    val place = activeLookup.map(_.getPsiElement).orNull
    val allLookups = lookups(isValid)

    Assert.assertTrue(allLookups.nonEmpty)

    allLookups.foreach { lookup =>
      val psiElement = lookup.getPsiElement
      val vFile = psiElement.getContainingFile.getVirtualFile
      Assert.assertTrue(s"Module scope doesn't contain element from ${vFile.getCanonicalPath}", scope.contains(vFile))

      if (checkAccessibility) {
        psiElement match {
          case m: PsiMember =>
            val qName = m.qualifiedNameOpt.getOrElse(m.getName)
            Assert.assertTrue(s"$qName is not accessible", ResolveUtils.isAccessible(m, place, forCompletion = true))
        }
      }
    }
  }

  private def isValid(lookup: LookupElement): Boolean = {
    lookup.getPsiElement match {
      case _: SyntheticNamedElement => false
      case _: PsiPackage            => false
      case _: PsiNamedElement       => true
      case _                        => false
    }
  }

  def testBasicCompletion0(): Unit = checkCompletionsAreInScopeAndAccessible("File", BASIC, 0)
  def testBasicCompletion1(): Unit = checkCompletionsAreInScopeAndAccessible("File", BASIC, 1)
  def testBasicCompletion2(): Unit = checkCompletionsAreInScopeAndAccessible("File", BASIC, 2)

  def testTypeCompletion1(): Unit = checkCompletionsAreInScopeAndAccessible("null: ", BASIC, 1)
  def testTypeCompletion2(): Unit = checkCompletionsAreInScopeAndAccessible("null: ", BASIC, 2)

  def testAfterDotCompletion1(): Unit = checkCompletionsAreInScopeAndAccessible("\"\".", BASIC, 1)
  def testAfterDotCompletion2(): Unit = checkCompletionsAreInScopeAndAccessible("\"\".", BASIC, 2)

  def testBasicCompletion1EmptyPrefix(): Unit = checkCompletionsAreInScopeAndAccessible("", BASIC, 1)
}
{'fraction_non_alphanumeric': 0.09396751740139211, 'fraction_numerical': 0.0063805104408352666, 'mean_word_length': 3.9644913627639156, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 15, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5941198', 'n_tokens_mistral': 1555, 'n_tokens_neox': 1483, 'n_words': 292}