[JS][Tests] Add test for JS klib resolver

^KT-70146
diff --git a/compiler/util-klib-metadata/src/org/jetbrains/kotlin/library/metadata/resolver/impl/KotlinLibraryResolverImpl.kt b/compiler/util-klib-metadata/src/org/jetbrains/kotlin/library/metadata/resolver/impl/KotlinLibraryResolverImpl.kt
index 6853f41..be6c4e8 100644
--- a/compiler/util-klib-metadata/src/org/jetbrains/kotlin/library/metadata/resolver/impl/KotlinLibraryResolverImpl.kt
+++ b/compiler/util-klib-metadata/src/org/jetbrains/kotlin/library/metadata/resolver/impl/KotlinLibraryResolverImpl.kt
@@ -113,7 +113,7 @@
         var newDependencies = rootLibraries
         do {
             newDependencies = newDependencies.map { library: KotlinResolvedLibraryImpl ->
-                library.library.unresolvedDependencies(lenient = true).asSequence()
+                library.library.unresolvedDependencies(resolveManifestDependenciesLenient).asSequence()
 
                     .filterNot { searchPathResolver.isProvidedByDefault(it) }
                     .mapNotNull { searchPathResolver.resolve(it)?.let(::KotlinResolvedLibraryImpl) }
diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/testOld/klib/JsKlibResolverTest.kt b/js/js.tests/test/org/jetbrains/kotlin/js/testOld/klib/JsKlibResolverTest.kt
index 0d1d646..b766c71 100644
--- a/js/js.tests/test/org/jetbrains/kotlin/js/testOld/klib/JsKlibResolverTest.kt
+++ b/js/js.tests/test/org/jetbrains/kotlin/js/testOld/klib/JsKlibResolverTest.kt
@@ -7,16 +7,29 @@
 
 import org.jetbrains.kotlin.cli.common.ExitCode
 import org.jetbrains.kotlin.cli.js.K2JSCompiler
+import org.jetbrains.kotlin.js.config.EcmaVersion
 import org.jetbrains.kotlin.test.TestCaseWithTmpdir
 import org.jetbrains.kotlin.test.services.StandardLibrariesPathProviderForKotlinProject
 import org.jetbrains.kotlin.test.util.JUnit4Assertions
 import org.jetbrains.kotlin.test.utils.assertCompilerOutputHasKlibResolverIncompatibleAbiMessages
 import org.jetbrains.kotlin.test.utils.patchManifestToBumpAbiVersion
+import org.junit.jupiter.api.DisplayName
 import java.io.ByteArrayOutputStream
 import java.io.File
 import java.io.PrintStream
 
 class JsKlibResolverTest : TestCaseWithTmpdir() {
+    private data class Module(val name: String, val dependencyNames: List<String>) {
+        constructor(name: String, vararg dependencyNames: String) : this(name, dependencyNames.asList())
+
+        lateinit var dependencies: List<Module>
+        lateinit var sourceFile: File
+
+        fun initDependencies(resolveDependency: (String) -> Module) {
+            dependencies = dependencyNames.map(resolveDependency)
+        }
+    }
+
     fun testWarningAboutRejectedLibraryIsNotSuppressed() {
         val testDataDir = File("compiler/testData/klib/resolve/mismatched-abi-version")
 
@@ -50,6 +63,34 @@
         assertCompilerOutputHasKlibResolverIncompatibleAbiMessages(JUnit4Assertions, result.output, missingLibrary = "/v2/lib1", tmpdir)
     }
 
+    @DisplayName("Test resolving nonexistent transitive dependency recorded in `depends` property (KT-70146)")
+    fun testResolvingTransitiveDependenciesRecordedInManifest() {
+        val moduleA = Module("a")
+        val moduleB = Module("b", "a")
+        val moduleC = Module("c", "b")
+        val modules = createModules(moduleA, moduleB, moduleC)
+
+        println(modules)
+        val aKlib = tmpdir.resolve("a.klib").also { it.mkdirs() }
+        val resultA = compileKlib(moduleA.sourceFile, dependency = null, outputFile = aKlib)
+        assertEquals(ExitCode.OK, resultA.exitCode)
+
+        val bKlib = tmpdir.resolve("b.klib").also { it.mkdirs() }
+        val resultB = compileKlib(moduleB.sourceFile, dependency = aKlib, outputFile = bKlib)
+        assertEquals(ExitCode.OK, resultB.exitCode)
+
+        // remove transitive dependency `a`, to check that subsequent compilation of `c` would not fail,
+        // since resolve on 1-st stage is performed without dependencies
+        aKlib.deleteRecursively()
+        val cKlib = tmpdir.resolve("c.klib").also { it.mkdirs() }
+        val resultC = compileKlib(moduleC.sourceFile, dependency = bKlib, outputFile = cKlib)
+        assertEquals(ExitCode.OK, resultC.exitCode)
+
+        val resultJS = compileToJs(moduleC.sourceFile, dependency = bKlib, outputFile = tmpdir)
+        println(resultJS.output)
+        assertEquals(ExitCode.OK, resultJS.exitCode)
+    }
+
     private fun createKlibDir(name: String, version: Int): File =
         tmpdir.resolve("v$version").resolve(name).apply(File::mkdirs)
 
@@ -75,6 +116,29 @@
         return CompilationResult(exitCode, compilerXmlOutput.toString())
     }
 
+    private fun compileToJs(sourceFile: File, dependency: File?, outputFile: File): CompilationResult {
+        val libraries = listOfNotNull(
+            StandardLibrariesPathProviderForKotlinProject.fullJsStdlib(),
+            dependency
+        ).joinToString(File.pathSeparator) { it.absolutePath }
+
+        val args = arrayOf(
+            "-Xir-produce-js",
+            "-libraries", libraries,
+            "-ir-output-dir", outputFile.absolutePath,
+            "-ir-output-name", outputFile.nameWithoutExtension,
+            "-target", EcmaVersion.defaultVersion(),
+            sourceFile.absolutePath
+        )
+
+        val compilerXmlOutput = ByteArrayOutputStream()
+        val exitCode = PrintStream(compilerXmlOutput).use { printStream ->
+            K2JSCompiler().execFullPathsInMessages(printStream, args)
+        }
+
+        return CompilationResult(exitCode, compilerXmlOutput.toString())
+    }
+
     private data class CompilationResult(val exitCode: ExitCode, val output: String) {
         fun assertSuccess() = JUnit4Assertions.assertTrue(exitCode == ExitCode.OK) {
             buildString {
@@ -92,4 +156,34 @@
             }
         }
     }
+
+    private fun createModules(vararg modules: Module): List<Module> {
+        val mapping: Map<String, Module> = modules.groupBy(Module::name).mapValues {
+            it.value.singleOrNull() ?: error("Duplicated modules: ${it.value}")
+        }
+
+        modules.forEach { it.initDependencies(mapping::getValue) }
+
+        val generatedSourcesDir = tmpdir.resolve("generated-sources")
+        generatedSourcesDir.mkdirs()
+
+        modules.forEach { module ->
+            module.sourceFile = generatedSourcesDir.resolve(module.name + ".kt")
+            module.sourceFile.writeText(
+                buildString {
+                    appendLine("package ${module.name}")
+                    appendLine()
+                    appendLine("fun ${module.name}(indent: Int) {")
+                    appendLine("    repeat(indent) { print(\"  \") }")
+                    appendLine("    println(\"${module.name}\")")
+                    module.dependencyNames.forEach { dependencyName ->
+                        appendLine("    $dependencyName.$dependencyName(indent + 1)")
+                    }
+                    appendLine("}")
+                }
+            )
+        }
+
+        return modules.asList()
+    }
 }
diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/KonanConfig.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/KonanConfig.kt
index 670148f..5f08471 100644
--- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/KonanConfig.kt
+++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/KonanConfig.kt
@@ -296,7 +296,7 @@
         get() = configuration.getBoolean(KonanConfigKeys.PURGE_USER_LIBS)
 
     internal val resolve = KonanLibrariesResolveSupport(
-            configuration, target, distribution, resolveManifestDependenciesLenient = metadataKlib
+            configuration, target, distribution, resolveManifestDependenciesLenient = true
     )
 
     val resolvedLibraries get() = resolve.resolvedLibraries