KT-3008 Add tests for module wrappers

This commit is contained in:
Alexey Andreev
2016-04-20 12:33:09 +03:00
parent 0cfacfa44a
commit e38b83880f
10 changed files with 171 additions and 8 deletions
+1
View File
@@ -16,5 +16,6 @@
<orderEntry type="library" name="idea-full" level="project" />
<orderEntry type="module" module-name="backend-common" scope="TEST" />
<orderEntry type="module" module-name="util" />
<orderEntry type="module" module-name="js.serializer" />
</component>
</module>
@@ -81,6 +81,7 @@ public abstract class BasicTest extends KotlinTestWithEnvironment {
private static final String OUT = "out/";
private static final String EXPECTED = "expected/";
private static final String COMMON_FILES_DIR = "_commonFiles/";
public static final String MODULE_EMULATION_FILE = TEST_DATA_DIR_PATH + "/moduleEmulation.js";
public static final String TEST_MODULE = "JS_TESTS";
public static final String TEST_PACKAGE = "foo";
@@ -346,6 +347,8 @@ public abstract class BasicTest extends KotlinTestWithEnvironment {
configuration.put(JSConfigurationKeys.UNIT_TEST_CONFIG, shouldBeTranslateAsUnitTestClass());
setupConfig(configBuilder);
return new LibrarySourcesConfig(project, configuration);
}
@@ -359,6 +362,10 @@ public abstract class BasicTest extends KotlinTestWithEnvironment {
return false;
}
protected void setupConfig(@NotNull CompilerConfiguration configuration) {
// Do nothing by default, expect inheritors to implement this method
}
@NotNull
protected String getOutputPath() {
return pathToTestDir() + OUT;
@@ -16,22 +16,24 @@
package org.jetbrains.kotlin.js.test
import com.google.dart.compiler.backend.js.ast.JsProgram
import com.intellij.openapi.util.io.FileUtil
import com.intellij.openapi.util.text.StringUtil
import org.jetbrains.kotlin.js.config.Config
import org.jetbrains.kotlin.js.config.EcmaVersion
import org.jetbrains.kotlin.js.config.LibrarySourcesConfig
import org.jetbrains.kotlin.js.facade.MainCallParameters
import org.jetbrains.kotlin.js.test.rhino.RhinoFunctionResultChecker
import org.jetbrains.kotlin.js.test.utils.DirectiveTestUtils
import org.jetbrains.kotlin.js.test.utils.JsTestUtils
import org.jetbrains.kotlin.js.test.utils.JsTestUtils.getAllFilesInDir
import org.jetbrains.kotlin.psi.KtFile
import org.jetbrains.kotlin.serialization.js.ModuleKind
import org.jetbrains.kotlin.utils.KotlinJavascriptMetadataUtils
import java.io.File
import java.util.ArrayList
import java.util.LinkedHashMap
abstract class MultipleModulesTranslationTest(main: String) : BasicTest(main) {
private val MAIN_MODULE_NAME: String = "main"
private var dependencies: Map<String, List<String>>? = null
protected var moduleKind = ModuleKind.PLAIN
override fun checkFooBoxIsOkByPath(filePath: String) {
val dirName = getTestName(true)
@@ -68,10 +70,23 @@ abstract class MultipleModulesTranslationTest(main: String) : BasicTest(main) {
private fun getMetaFileOutputPath(moduleDirectoryName: String, version: EcmaVersion) =
KotlinJavascriptMetadataUtils.replaceSuffix(getOutputFilePath(moduleDirectoryName, version))
override fun setupConfig(builder: LibrarySourcesConfig.Builder) {
val method = try {
javaClass.getMethod(name)
}
catch (e: NoSuchMethodException) {
return
}
method.getAnnotation(WithModuleKind::class.java)?.let { moduleKind = it.value }
builder.moduleKind(moduleKind)
}
override fun shouldGenerateMetaInfo() = true
override fun additionalJsFiles(ecmaVersion: EcmaVersion): List<String> {
val result = super.additionalJsFiles(ecmaVersion)
val result = mutableListOf(MODULE_EMULATION_FILE)
result += super.additionalJsFiles(ecmaVersion)
val dirName = getTestName(true)
assert(dependencies != null) { "dependencies should not be null" }
@@ -84,6 +99,20 @@ abstract class MultipleModulesTranslationTest(main: String) : BasicTest(main) {
return result
}
override fun translateFiles(jetFiles: MutableList<KtFile>, outputFile: File, mainCallParameters: MainCallParameters,
config: Config) {
super.translateFiles(jetFiles, outputFile, mainCallParameters, config)
if (config.moduleKind == ModuleKind.COMMON_JS) {
val content = FileUtil.loadFile(outputFile, true)
val wrappedContent = "__beginModule__();\n" +
"$content\n" +
"__endModule__(\"${StringUtil.escapeStringCharacters(config.moduleId)}\");"
FileUtil.writeToFile(outputFile, wrappedContent)
// TODO: it would be better to wrap output before JS file is actually written
}
}
private fun readModuleDependencies(testDataDir: String): Map<String, List<String>> {
val dependenciesTxt = upsearchFile(testDataDir, "dependencies.txt")
assert(dependenciesTxt.isFile) { "moduleDependencies should not be null" }
@@ -0,0 +1,23 @@
/*
* Copyright 2010-2016 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.js.test
import org.jetbrains.kotlin.serialization.js.ModuleKind
@Retention(AnnotationRetention.RUNTIME)
@Target(AnnotationTarget.FUNCTION)
annotation class WithModuleKind(val value: ModuleKind)
@@ -55,10 +55,10 @@ public class RhinoFunctionResultChecker implements RhinoResultChecker {
return cx.evaluateString(scope, functionCallString(), "function call", 0, null);
}
protected String functionCallString() {
private String functionCallString() {
StringBuilder sb = new StringBuilder();
if (packageName != null) {
sb.append("this");
sb.append("kotlin.modules");
if (moduleId.contains(".")) {
sb.append("['").append(moduleId).append("']");
} else {
@@ -0,0 +1,66 @@
/*
* Copyright 2010-2016 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/*
* Copyright 2010-2016 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.jetbrains.kotlin.js.test.semantics
import org.jetbrains.kotlin.js.test.MultipleModulesTranslationTest
import org.jetbrains.kotlin.js.test.WithModuleKind
import org.jetbrains.kotlin.serialization.js.ModuleKind
class MultiModuleWrappersTest() : MultipleModulesTranslationTest("multiModuleWrappers/") {
private var overridenTestName = ""
@WithModuleKind(ModuleKind.AMD) fun testAmd() {
runTest("simple")
}
@WithModuleKind(ModuleKind.COMMON_JS) fun testCommonJs() {
runTest("simple")
}
@WithModuleKind(ModuleKind.UMD) fun testUmd() {
runTest("simple")
}
@WithModuleKind(ModuleKind.UMD) fun testPlain() {
runTest("simple")
}
fun runTest(name: String) {
overridenTestName = name
doTest("${pathToTestDir()}/cases/$name")
}
override fun getTestName(lowercaseFirstLetter: Boolean) = overridenTestName
override fun getOutputPath() = "${super.getOutputPath()}/${moduleKind.name.toLowerCase()}/"
}
+30
View File
@@ -0,0 +1,30 @@
(function(global) {
var modules = { kotlin: kotlin };
var module = { exports: {} };
function require(moduleId) {
return modules[moduleId];
}
function beginModule() {
module.exports = {};
}
function endModule(moduleId) {
modules[moduleId] = module.exports;
}
function define(moduleId, dependencies, body) {
var resolvedDependencies = [];
for (var i = 0; i < dependencies.length; ++i) {
resolvedDependencies.push(modules[dependencies[i]]);
}
modules[moduleId] = body.apply(null, resolvedDependencies);
}
global.require = require;
global.define = define;
global.__beginModule__ = beginModule;
global.__endModule__ = endModule;
global.module = module;
})(this);
@@ -0,0 +1,2 @@
module1->
main->module1
@@ -0,0 +1,4 @@
fun box(): String {
assertEquals("bar", bar())
return "OK"
}
@@ -0,0 +1 @@
fun bar() = "bar"