[JS TESTS] Rewrite web demo tests using new test infrastructure

This commit is contained in:
Ivan Kylchik
2021-10-20 22:15:16 +03:00
parent af0e40a0d2
commit 8a1362de03
45 changed files with 369 additions and 579 deletions
@@ -134,6 +134,12 @@ object JsEnvironmentConfigurationDirectives : SimpleDirectivesContainer() {
applicability = DirectiveApplicability.Global, applicability = DirectiveApplicability.Global,
) )
val MAIN_ARGS by valueDirective(
description = "Specify arguments that will be passes to main fun",
applicability = DirectiveApplicability.Global,
parser = { it.subSequence(1, it.length - 1).split(",") }
)
// Next directives are used only inside test system and must not be present in test file // Next directives are used only inside test system and must not be present in test file
val PATH_TO_TEST_DIR by stringDirective( val PATH_TO_TEST_DIR by stringDirective(
@@ -15,11 +15,11 @@ import org.jetbrains.kotlin.js.test.es6.semantics.AbstractIrJsCodegenBoxES6Test
import org.jetbrains.kotlin.js.test.es6.semantics.AbstractIrJsCodegenInlineES6Test import org.jetbrains.kotlin.js.test.es6.semantics.AbstractIrJsCodegenInlineES6Test
import org.jetbrains.kotlin.js.test.es6.semantics.AbstractIrJsTypeScriptExportES6Test import org.jetbrains.kotlin.js.test.es6.semantics.AbstractIrJsTypeScriptExportES6Test
import org.jetbrains.kotlin.js.test.ir.semantics.* import org.jetbrains.kotlin.js.test.ir.semantics.*
import org.jetbrains.kotlin.js.test.semantics.*
import org.jetbrains.kotlin.js.test.wasm.semantics.AbstractIrCodegenBoxWasmTest import org.jetbrains.kotlin.js.test.wasm.semantics.AbstractIrCodegenBoxWasmTest
import org.jetbrains.kotlin.js.test.wasm.semantics.AbstractIrCodegenWasmJsInteropWasmTest import org.jetbrains.kotlin.js.test.wasm.semantics.AbstractIrCodegenWasmJsInteropWasmTest
import org.jetbrains.kotlin.js.test.wasm.semantics.AbstractJsTranslatorWasmTest import org.jetbrains.kotlin.js.test.wasm.semantics.AbstractJsTranslatorWasmTest
import org.jetbrains.kotlin.js.testNew.* import org.jetbrains.kotlin.js.testNew.*
import org.jetbrains.kotlin.js.testNew.AbstractWebDemoExamplesTest
import org.jetbrains.kotlin.test.TargetBackend import org.jetbrains.kotlin.test.TargetBackend
fun main(args: Array<String>) { fun main(args: Array<String>) {
@@ -137,6 +137,10 @@ fun main(args: Array<String>) {
testClass<AbstractMultiModuleOrderTest> { testClass<AbstractMultiModuleOrderTest> {
model("multiModuleOrder/") model("multiModuleOrder/")
} }
testClass<AbstractWebDemoExamplesTest> {
model("webDemoExamples/")
}
} }
testGroup("js/js.tests/tests-gen", "compiler/testData", testRunnerMethodName = "runTest0") { testGroup("js/js.tests/tests-gen", "compiler/testData", testRunnerMethodName = "runTest0") {
@@ -1,40 +0,0 @@
/*
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.js.test.semantics
import com.google.common.collect.Lists
import com.intellij.openapi.util.text.StringUtil
import org.jetbrains.kotlin.js.facade.MainCallParameters
import org.jetbrains.kotlin.js.test.BasicBoxTest
import java.io.File
import javax.script.ScriptException
abstract class AbstractWebDemoExamplesTest(relativePath: String) : BasicBoxTest(
BasicBoxTest.TEST_DATA_DIR_PATH + "/$relativePath/",
relativePath,
generateNodeJsRunner = false
) {
override fun runGeneratedCode(
jsFiles: List<String>,
testModuleName: String?,
testPackage: String?,
testFunction: String,
expectedResult: String,
withModuleSystem: Boolean
) {
testChecker.checkStdout(jsFiles, expectedResult)
}
@Throws(ScriptException::class)
protected fun runMainAndCheckOutput(fileName: String, expectedResult: String, vararg args: String) {
doTest(pathToTestDir + fileName, expectedResult, MainCallParameters.mainWithArguments(Lists.newArrayList(*args)))
}
protected fun runMainAndCheckOutputWithExpectedFile(testName: String, testId: String, vararg args: String) {
val expectedResult = StringUtil.convertLineSeparators(File(pathToTestDir + testName + testId + ".out").readText())
doTest(pathToTestDir + testName + ".kt", expectedResult, MainCallParameters.mainWithArguments(Lists.newArrayList(*args)))
}
}
@@ -1,93 +0,0 @@
/*
* Copyright 2010-2015 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;
public final class WebDemoExamples1Test extends AbstractWebDemoExamplesTest {
public WebDemoExamples1Test() {
super("webDemoExamples1/");
}
public void testPrintArg() throws Exception {
runMainAndCheckOutput("printArg.kt", "Hello, world!", "Hello, world!");
}
public void testWhileLoop() throws Exception {
runMainAndCheckOutput("whileLoop.kt", "guest1\nguest2\nguest3\nguest4\n", "guest1", "guest2", "guest3", "guest4");
}
public void testIfAsExpression() throws Exception {
runMainAndCheckOutput("ifAsExpression.kt", "20\n", "10", "20");
}
public void testObjectOrientedHello() throws Exception {
runMainAndCheckOutput("objectOrientedHello.kt", "Hello, Pavel!\n", "Pavel");
}
public void testMultiLanguageHello() throws Exception {
runMainAndCheckOutput("multiLanguageHello.kt", "Salut!\n", "FR");
}
public void testNullChecks() throws Exception {
runMainAndCheckOutput("nullChecks.kt", "No number supplied");
runMainAndCheckOutput("nullChecks.kt", "6", "2", "3");
}
public void testRanges() throws Exception {
runMainAndCheckOutput("ranges.kt", "OK\n" +
" 1 2 3 4 5\n" +
"Out: array has only 3 elements. x = 4\n" +
"Yes: array contains aaa\n" +
"No: array doesn't contains ddd\n", "4");
runMainAndCheckOutput("ranges.kt", " 1 2 3 4 5\n" +
"Out: array has only 3 elements. x = 10\n" +
"Yes: array contains aaa\n" +
"No: array doesn't contains ddd\n", "10");
}
public void testForLoop() throws Exception {
runMainAndCheckOutput("forLoop.kt", "a\n" +
"b\n" +
"c\n" +
"\n" +
"a\n" +
"b\n" +
"c\n", "a", "b", "c");
runMainAndCheckOutput("forLoop.kt", "123\n\n123\n", "123");
}
public void testIsCheck() throws Exception {
runMainAndCheckOutput("isCheck.kt", "3\nnull\n");
}
public void testPatternMatching() throws Exception {
runMainAndCheckOutput("patternMatching.kt", "Greeting\n" +
"One\n" +
"Not a string\n" +
"Unknown\n");
}
}
@@ -1,38 +0,0 @@
/*
* Copyright 2010-2015 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;
public final class WebDemoExamples2Test extends AbstractWebDemoExamplesTest {
public WebDemoExamples2Test() {
super("webDemoExamples2/");
}
public void testBottles() throws Exception {
runMainAndCheckOutputWithExpectedFile("bottles", "2", "2");
runMainAndCheckOutputWithExpectedFile("bottles", "");
}
public void testLife() throws Exception {
runMainAndCheckOutputWithExpectedFile("life", "", "2");
}
public void testBuilder() throws Exception {
runMainAndCheckOutputWithExpectedFile("builder", "");
runMainAndCheckOutputWithExpectedFile("builder", "1", "over9000");
}
}
@@ -136,3 +136,22 @@ open class AbstractMultiModuleOrderTest : AbstractJsTest(
} }
} }
} }
open class AbstractWebDemoExamplesTest : AbstractJsTest(
pathToTestDir = "${JsEnvironmentConfigurator.TEST_DATA_DIR_PATH}/webDemoExamples/",
testGroupOutputDirPrefix = "webDemoExamples/"
) {
override fun configure(builder: TestConfigurationBuilder) {
super.configure(builder)
with(builder) {
defaultDirectives {
-JsEnvironmentConfigurationDirectives.GENERATE_NODE_JS_RUNNER
JsEnvironmentConfigurationDirectives.DONT_RUN_GENERATED_CODE.with("JS")
}
configureJsArtifactsHandlersStep {
useHandlers(::MainCallWithArgumentsHandler)
}
}
}
}
@@ -5,6 +5,7 @@
package org.jetbrains.kotlin.js.testNew.converters package org.jetbrains.kotlin.js.testNew.converters
import com.google.common.collect.Lists
import com.intellij.openapi.util.io.FileUtil import com.intellij.openapi.util.io.FileUtil
import com.intellij.openapi.util.text.StringUtil import com.intellij.openapi.util.text.StringUtil
import org.jetbrains.kotlin.cli.common.output.writeAllTo import org.jetbrains.kotlin.cli.common.output.writeAllTo
@@ -82,8 +83,11 @@ class ClassicJsBackendFacade(
val units = unitsByPath.entries.sortedBy { it.key }.map { it.value } val units = unitsByPath.entries.sortedBy { it.key }.map { it.value }
val mainCallParameters = when (JsEnvironmentConfigurationDirectives.CALL_MAIN) { val mainCallParameters = when {
in module.directives -> MainCallParameters.mainWithArguments(listOf()) JsEnvironmentConfigurationDirectives.CALL_MAIN in module.directives -> MainCallParameters.mainWithArguments(listOf())
JsEnvironmentConfigurationDirectives.MAIN_ARGS in module.directives -> {
MainCallParameters.mainWithArguments(module.directives[JsEnvironmentConfigurationDirectives.MAIN_ARGS].first())
}
else -> MainCallParameters.noCall() else -> MainCallParameters.noCall()
} }
@@ -0,0 +1,26 @@
/*
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.js.testNew.handlers
import org.jetbrains.kotlin.js.testNew.utils.getOnlyJsFilesForRunner
import org.jetbrains.kotlin.js.testNew.utils.getTestChecker
import org.jetbrains.kotlin.test.services.TestServices
import org.jetbrains.kotlin.test.services.moduleStructure
class MainCallWithArgumentsHandler(testServices: TestServices) : AbstractJsArtifactsCollector(testServices) {
override fun processAfterAllModules(someAssertionWasFailed: Boolean) {
if (someAssertionWasFailed) return
val testFile = testServices.moduleStructure.originalTestDataFiles.first()
val expectedFile = testFile.parentFile.resolve(testFile.nameWithoutExtension + ".out")
if (!expectedFile.exists()) {
throw IllegalArgumentException("File ${expectedFile.absolutePath} with expected result doesn't exists")
}
val allJsFiles = getOnlyJsFilesForRunner(testServices, modulesToArtifact)
getTestChecker(testServices).checkStdout(allJsFiles, expectedFile.readText())
}
}
@@ -0,0 +1,129 @@
/*
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.js.testNew;
import com.intellij.testFramework.TestDataPath;
import org.jetbrains.kotlin.test.util.KtTestUtil;
import org.jetbrains.kotlin.test.TargetBackend;
import org.jetbrains.kotlin.test.TestMetadata;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import java.io.File;
import java.util.regex.Pattern;
/** This class is generated by {@link GenerateNewCompilerTests.kt}. DO NOT MODIFY MANUALLY */
@SuppressWarnings("all")
@TestMetadata("js/js.translator/testData/webDemoExamples")
@TestDataPath("$PROJECT_ROOT")
public class WebDemoExamplesTestGenerated extends AbstractWebDemoExamplesTest {
@Test
public void testAllFilesPresentInWebDemoExamples() throws Exception {
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("js/js.translator/testData/webDemoExamples"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JS, true);
}
@Test
@TestMetadata("bottles.kt")
public void testBottles() throws Exception {
runTest("js/js.translator/testData/webDemoExamples/bottles.kt");
}
@Test
@TestMetadata("builder.kt")
public void testBuilder() throws Exception {
runTest("js/js.translator/testData/webDemoExamples/builder.kt");
}
@Test
@TestMetadata("forLoop1.kt")
public void testForLoop1() throws Exception {
runTest("js/js.translator/testData/webDemoExamples/forLoop1.kt");
}
@Test
@TestMetadata("forLoop2.kt")
public void testForLoop2() throws Exception {
runTest("js/js.translator/testData/webDemoExamples/forLoop2.kt");
}
@Test
@TestMetadata("ifAsExpression.kt")
public void testIfAsExpression() throws Exception {
runTest("js/js.translator/testData/webDemoExamples/ifAsExpression.kt");
}
@Test
@TestMetadata("isCheck.kt")
public void testIsCheck() throws Exception {
runTest("js/js.translator/testData/webDemoExamples/isCheck.kt");
}
@Test
@TestMetadata("life.kt")
public void testLife() throws Exception {
runTest("js/js.translator/testData/webDemoExamples/life.kt");
}
@Test
@TestMetadata("maze.kt")
public void testMaze() throws Exception {
runTest("js/js.translator/testData/webDemoExamples/maze.kt");
}
@Test
@TestMetadata("multiLanguageHello.kt")
public void testMultiLanguageHello() throws Exception {
runTest("js/js.translator/testData/webDemoExamples/multiLanguageHello.kt");
}
@Test
@TestMetadata("nullChecks1.kt")
public void testNullChecks1() throws Exception {
runTest("js/js.translator/testData/webDemoExamples/nullChecks1.kt");
}
@Test
@TestMetadata("nullChecks2.kt")
public void testNullChecks2() throws Exception {
runTest("js/js.translator/testData/webDemoExamples/nullChecks2.kt");
}
@Test
@TestMetadata("objectOrientedHello.kt")
public void testObjectOrientedHello() throws Exception {
runTest("js/js.translator/testData/webDemoExamples/objectOrientedHello.kt");
}
@Test
@TestMetadata("patternMatching.kt")
public void testPatternMatching() throws Exception {
runTest("js/js.translator/testData/webDemoExamples/patternMatching.kt");
}
@Test
@TestMetadata("printArg.kt")
public void testPrintArg() throws Exception {
runTest("js/js.translator/testData/webDemoExamples/printArg.kt");
}
@Test
@TestMetadata("ranges1.kt")
public void testRanges1() throws Exception {
runTest("js/js.translator/testData/webDemoExamples/ranges1.kt");
}
@Test
@TestMetadata("ranges2.kt")
public void testRanges2() throws Exception {
runTest("js/js.translator/testData/webDemoExamples/ranges2.kt");
}
@Test
@TestMetadata("whileLoop.kt")
public void testWhileLoop() throws Exception {
runTest("js/js.translator/testData/webDemoExamples/whileLoop.kt");
}
}
@@ -1,3 +1,5 @@
// MAIN_ARGS: [2]
/** /**
* This example implements the famous "99 Bottles of Beer" program * This example implements the famous "99 Bottles of Beer" program
* See http://99-bottles-of-beer.net/ * See http://99-bottles-of-beer.net/
@@ -1,3 +1,5 @@
// MAIN_ARGS: [over9000]
/** /**
* This is an example of a Type-Safe Groovy-style Builder * This is an example of a Type-Safe Groovy-style Builder
* *
+11
View File
@@ -0,0 +1,11 @@
// MAIN_ARGS: [a,b,c]
fun main(args: Array<String>) {
for (arg in args)
println(arg)
// or
println()
for (i in args.indices)
println(args[i])
}
@@ -0,0 +1,7 @@
a
b
c
a
b
c
@@ -1,3 +1,5 @@
// MAIN_ARGS: [123]
fun main(args: Array<String>) { fun main(args: Array<String>) {
for (arg in args) for (arg in args)
println(arg) println(arg)
@@ -0,0 +1,3 @@
123
123
@@ -1,3 +1,5 @@
// MAIN_ARGS: [10,20]
fun main(args: Array<String>) { fun main(args: Array<String>) {
println(maxOf(args[0].toInt(), args[1].toInt())) println(maxOf(args[0].toInt(), args[1].toInt()))
} }
@@ -0,0 +1 @@
20
@@ -1,3 +1,5 @@
// MAIN_ARGS: []
fun main(args: Array<String>) { fun main(args: Array<String>) {
println(getStringLength("aaa")) println(getStringLength("aaa"))
println(getStringLength(1)) println(getStringLength(1))
+2
View File
@@ -0,0 +1,2 @@
3
null
@@ -1,3 +1,5 @@
// MAIN_ARGS: [2]
/** /**
* This is a straightforward implementation of The Game of Life * This is a straightforward implementation of The Game of Life
* See http://en.wikipedia.org/wiki/Conway's_Game_of_Life * See http://en.wikipedia.org/wiki/Conway's_Game_of_Life
@@ -1,3 +1,5 @@
// MAIN_ARGS: []
/** /**
* Let's Walk Through a Maze. * Let's Walk Through a Maze.
* *
@@ -19,16 +21,19 @@
* as I possibly can by finding a shortest path through the maze. * as I possibly can by finding a shortest path through the maze.
*/ */
fun <E> MutableList<E>.offer(element: E) = this.add(element)
fun <E> MutableList<E>.poll() = this.removeAt(0)
/** /**
* This function looks for a path from max.start to maze.end through * This function looks for a path from max.start to maze.end through
* free space (a path does not go through walls). One can move only * free space (a path does not go through walls). One can move only
* straightly up, down, left or right, no diagonal moves allowed. * straightly up, down, left or right, no diagonal moves allowed.
*/ */
fun findPath(maze: Maze): List<Pair<Int, Int>>? { fun findPath(maze: Maze): List<Pair<Int, Int>>? {
val previous = HashMap<Pair<Int, Int>, Pair<Int, Int>> val previous = HashMap<Pair<Int, Int>, Pair<Int, Int>>()
val queue = LinkedList<Pair<Int, Int>> val queue = ArrayDeque<Pair<Int, Int>>()
val visited = HashSet<Pair<Int, Int>> val visited = HashSet<Pair<Int, Int>>()
queue.offer(maze.start) queue.offer(maze.start)
visited.add(maze.start) visited.add(maze.start)
@@ -36,7 +41,7 @@ fun findPath(maze: Maze): List<Pair<Int, Int>>? {
val cell = queue.poll() val cell = queue.poll()
if (cell == maze.end) break if (cell == maze.end) break
for (newCell in maze.neighbors(cell._1, cell._2)) { for (newCell in maze.neighbors(cell.first, cell.second)) {
if (newCell in visited) continue if (newCell in visited) continue
previous[newCell] = cell previous[newCell] = cell
queue.offer(newCell) queue.offer(newCell)
@@ -49,7 +54,7 @@ fun findPath(maze: Maze): List<Pair<Int, Int>>? {
val path = ArrayList<Pair<Int, Int>>() val path = ArrayList<Pair<Int, Int>>()
var current = previous[maze.end] var current = previous[maze.end]
while (current != maze.start) { while (current != maze.start) {
path.add(0, current) path.add(0, current!!)
current = previous[current] current = previous[current]
} }
return path return path
@@ -59,7 +64,7 @@ fun findPath(maze: Maze): List<Pair<Int, Int>>? {
* Find neighbors of the (i, j) cell that are not walls * Find neighbors of the (i, j) cell that are not walls
*/ */
fun Maze.neighbors(i: Int, j: Int): List<Pair<Int, Int>> { fun Maze.neighbors(i: Int, j: Int): List<Pair<Int, Int>> {
val result = ArrayList<Pair<Int, Int>> val result = ArrayList<Pair<Int, Int>>()
addIfFree(i - 1, j, result) addIfFree(i - 1, j, result)
addIfFree(i, j - 1, result) addIfFree(i, j - 1, result)
addIfFree(i + 1, j, result) addIfFree(i + 1, j, result)
@@ -67,7 +72,7 @@ fun Maze.neighbors(i: Int, j: Int): List<Pair<Int, Int>> {
return result return result
} }
fun Maze.addIfFree(i: Int, j: Int, result: List<Pair<Int, Int>>) { fun Maze.addIfFree(i: Int, j: Int, result: MutableList<Pair<Int, Int>>) {
if (i !in 0..height - 1) return if (i !in 0..height - 1) return
if (j !in 0..width - 1) return if (j !in 0..width - 1) return
if (walls[i][j]) return if (walls[i][j]) return
@@ -79,16 +84,16 @@ fun Maze.addIfFree(i: Int, j: Int, result: List<Pair<Int, Int>>) {
* A data class that represents a maze * A data class that represents a maze
*/ */
class Maze( class Maze(
// Number or columns // Number or columns
val width: Int, val width: Int,
// Number of rows // Number of rows
val height: Int, val height: Int,
// true for a wall, false for free space // true for a wall, false for free space
val walls: Array<out Array<out Boolean>>, val walls: Array<out Array<out Boolean>>,
// The starting point (must not be a wall) // The starting point (must not be a wall)
val start: Pair<Int, Int>, val start: Pair<Int, Int>,
// The target point (must not be a wall) // The target point (must not be a wall)
val end: Pair<Int, Int> val end: Pair<Int, Int>
) { ) {
} }
@@ -102,7 +107,7 @@ fun main(args: Array<String>) {
O O
O O
O I O I
""") """.trimIndent())
printMaze(""" printMaze("""
OOOOOOOOOOO OOOOOOOOOOO
O $ O O $ O
@@ -113,7 +118,7 @@ fun main(args: Array<String>) {
O OOOOOOOOO O OOOOOOOOO
O OO O OO
OOOOOO IO OOOOOO IO
""") """.trimIndent())
printMaze(""" printMaze("""
OOOOOOOOOOOOOOOOO OOOOOOOOOOOOOOOOO
O O O O
@@ -124,7 +129,7 @@ fun main(args: Array<String>) {
O O I O O O I O
O O O O
OOOOOOOOOOOOOOOOO OOOOOOOOOOOOOOOOO
""") """.trimIndent())
} }
// UTILITIES // UTILITIES
@@ -138,11 +143,11 @@ fun printMaze(str: String) {
for (j in 0..maze.width - 1) { for (j in 0..maze.width - 1) {
val cell = Pair(i, j) val cell = Pair(i, j)
print( print(
if (maze.walls[i][j]) "O" if (maze.walls[i][j]) "O"
else if (cell == maze.start) "I" else if (cell == maze.start) "I"
else if (cell == maze.end) "$" else if (cell == maze.end) "$"
else if (path != null && path.contains(cell)) "~" else if (path != null && path.contains(cell)) "~"
else " " else " "
) )
} }
println("") println("")
@@ -171,12 +176,12 @@ fun printMaze(str: String) {
*/ */
fun makeMaze(s: String): Maze { fun makeMaze(s: String): Maze {
val lines = s.split("\n")!! val lines = s.split("\n")!!
val w = max<String?>(lines.toList(), comparator<String?> { o1, o2 -> val w = lines.maxWithOrNull(Comparator { o1, o2 ->
val l1: Int = o1?.size ?: 0 val l1: Int = o1?.length ?: 0
val l2 = o2?.size ?: 0 val l2 = o2?.length ?: 0
l1 - l2 l1 - l2
})!! })!!
val data = Array<Array<Boolean>>(lines.size) { Array<Boolean>(w.size) { false } } val data = Array<Array<Boolean>>(lines.size) { Array<Boolean>(w.length) { false } }
var start: Pair<Int, Int>? = null var start: Pair<Int, Int>? = null
var end: Pair<Int, Int>? = null var end: Pair<Int, Int>? = null
@@ -202,24 +207,9 @@ fun makeMaze(s: String): Maze {
throw IllegalArgumentException("No goal point in the maze (should be indicated with a '$' sign)") throw IllegalArgumentException("No goal point in the maze (should be indicated with a '$' sign)")
} }
return Maze(w.size, lines.size, data, start!!, end!!) return Maze(w.length, lines.size, data, start!!, end!!)
} }
// An excerpt from the Standard Library // An excerpt from the Standard Library
val String?.indices: IntRange get() = IntRange(0, this!!.size) val String?.indices: IntRange get() = IntRange(0, this!!.length)
fun <K, V> Map<K, V>.set(k: K, v: V) {
put(k, v)
}
fun comparator<T> (f: (T, T) -> Int): Comparator<T> = object : Comparator<T> {
override fun compare(o1: T, o2: T): Int = f(o1, o2)
override fun equals(p: Any?): Boolean = false
}
fun <T, C : Collection<T>> Array<T>.to(result: C): C {
for (elem in this)
result.add(elem)
return result
}
@@ -7,39 +7,34 @@ I O $
Result: No path Result: No path
Maze: Maze:
O $
O $ O ~
O ~ O ~
O ~ O ~
O ~ O ~~~~~~~~~I
O ~~~~~~~~~I
Result: Path found Result: Path found
Maze: Maze:
OOOOOOOOOOO OOOOOOOOOOO
O $~~~~~ O O $~~~~~ O
OOOOOOO~OOO OOOOOOO~OOO
O ~~~ O O ~~~ O
OOOOO~OOOOO OOOOO~OOOOO
O~~~~~ O O~~~~~ O
O~OOOOOOOOO O~OOOOOOOOO
O~~~~~~ OO O~~~~~~ OO
OOOOOO~~~IO OOOOOO~~~IO
Result: Path found Result: Path found
Maze: Maze:
OOOOOOOOOOOOOOOOO OOOOOOOOOOOOOOOOO
O ~~~ O O ~~~ O
O$~~O~ O O$~~O~ O
OOOOO~ O OOOOO~ O
O ~~~~ O O ~~~~ O
O ~OOOOOOOOOOOOOO O ~OOOOOOOOOOOOOO
O ~ O I O O ~ O I O
O ~~~~~~~~~~~~~ O O ~~~~~~~~~~~~~ O
OOOOOOOOOOOOOOOOO OOOOOOOOOOOOOOOOO
Result: Path found Result: Path found
@@ -1,3 +1,5 @@
// MAIN_ARGS: [FR]
fun main(args: Array<String>) { fun main(args: Array<String>) {
val language = if (args.size == 0) "EN" else args[0] val language = if (args.size == 0) "EN" else args[0]
println(when (language) { println(when (language) {
@@ -0,0 +1 @@
Salut!
@@ -1,3 +1,5 @@
// MAIN_ARGS: []
// Return null if str does not hold a number // Return null if str does not hold a number
fun myParseInt(str: String): Int? = str.toIntOrNull().also { fun myParseInt(str: String): Int? = str.toIntOrNull().also {
if (it == null) println("One of arguments isn't Int") if (it == null) println("One of arguments isn't Int")
@@ -0,0 +1 @@
No number supplied
@@ -0,0 +1,21 @@
// MAIN_ARGS: [2,3]
// Return null if str does not hold a number
fun myParseInt(str: String): Int? = str.toIntOrNull().also {
if (it == null) println("One of arguments isn't Int")
}
fun main(args: Array<String>) {
if (args.size < 2) {
print("No number supplied");
}
else {
val x = myParseInt(args[0])
val y = myParseInt(args[1])
// We cannot say 'x * y' now because they may hold nulls
if (x != null && y != null) {
print(x * y) // Now we can
}
}
}
@@ -0,0 +1 @@
6
@@ -1,3 +1,5 @@
// MAIN_ARGS: [Pavel]
class Greeter(name: String) { class Greeter(name: String) {
val name = name val name = name
fun greet() { fun greet() {
@@ -0,0 +1 @@
Hello, Pavel!
@@ -1,3 +1,5 @@
// MAIN_ARGS: []
fun main(args: Array<String>) { fun main(args: Array<String>) {
cases("Hello") cases("Hello")
cases(1) cases(1)
@@ -0,0 +1,4 @@
Greeting
One
Not a string
Unknown
@@ -1,3 +1,5 @@
// MAIN_ARGS: [Hello_world!]
fun main(args: Array<String>) { fun main(args: Array<String>) {
print(args[0]); print(args[0]);
} }
@@ -0,0 +1 @@
Hello_world!
@@ -1,3 +1,4 @@
// MAIN_ARGS: [4]
fun main(args: Array<String>) { fun main(args: Array<String>) {
val x = args[0].toInt() val x = args[0].toInt()
+5
View File
@@ -0,0 +1,5 @@
OK
1 2 3 4 5
Out: array has only 3 elements. x = 4
Yes: array contains aaa
No: array doesn't contains ddd
+35
View File
@@ -0,0 +1,35 @@
// MAIN_ARGS: [10]
fun main(args: Array<String>) {
val x = args[0].toInt()
//Check if a number lies within a range:
val y = 10
if (x in 1..y - 1)
println("OK")
//Iterate over a range:
for (a in 1..5)
print(" ${a}")
//Check if a number is out of range:
println()
val array = mutableListOf<String>()
array.add("aaa")
array.add("bbb")
array.add("ccc")
if (x !in 0..array.size)
println("Out: array has only ${array.size} elements. x = ${x}")
//Check if a collection contains an object:
if ("aaa" in array) // collection.contains(obj) is called
println("Yes: array contains aaa")
if ("ddd" in array) // collection.contains(obj) is called
println("Yes: array contains ddd")
else
println("No: array doesn't contains ddd")
}
+4
View File
@@ -0,0 +1,4 @@
1 2 3 4 5
Out: array has only 3 elements. x = 10
Yes: array contains aaa
No: array doesn't contains ddd
@@ -1,3 +1,5 @@
// MAIN_ARGS: [guest1,guest2,guest3,guest4]
fun main(args: Array<String>) { fun main(args: Array<String>) {
var i = 0 var i = 0
while (i < args.size) while (i < args.size)
@@ -0,0 +1,4 @@
guest1
guest2
guest3
guest4
-301
View File
@@ -1,301 +0,0 @@
The "99 bottles of beer" song
99 bottles of beer on the wall, 99 bottles of beer.
Take one down, pass it around, 98 bottles of beer on the wall.
98 bottles of beer on the wall, 98 bottles of beer.
Take one down, pass it around, 97 bottles of beer on the wall.
97 bottles of beer on the wall, 97 bottles of beer.
Take one down, pass it around, 96 bottles of beer on the wall.
96 bottles of beer on the wall, 96 bottles of beer.
Take one down, pass it around, 95 bottles of beer on the wall.
95 bottles of beer on the wall, 95 bottles of beer.
Take one down, pass it around, 94 bottles of beer on the wall.
94 bottles of beer on the wall, 94 bottles of beer.
Take one down, pass it around, 93 bottles of beer on the wall.
93 bottles of beer on the wall, 93 bottles of beer.
Take one down, pass it around, 92 bottles of beer on the wall.
92 bottles of beer on the wall, 92 bottles of beer.
Take one down, pass it around, 91 bottles of beer on the wall.
91 bottles of beer on the wall, 91 bottles of beer.
Take one down, pass it around, 90 bottles of beer on the wall.
90 bottles of beer on the wall, 90 bottles of beer.
Take one down, pass it around, 89 bottles of beer on the wall.
89 bottles of beer on the wall, 89 bottles of beer.
Take one down, pass it around, 88 bottles of beer on the wall.
88 bottles of beer on the wall, 88 bottles of beer.
Take one down, pass it around, 87 bottles of beer on the wall.
87 bottles of beer on the wall, 87 bottles of beer.
Take one down, pass it around, 86 bottles of beer on the wall.
86 bottles of beer on the wall, 86 bottles of beer.
Take one down, pass it around, 85 bottles of beer on the wall.
85 bottles of beer on the wall, 85 bottles of beer.
Take one down, pass it around, 84 bottles of beer on the wall.
84 bottles of beer on the wall, 84 bottles of beer.
Take one down, pass it around, 83 bottles of beer on the wall.
83 bottles of beer on the wall, 83 bottles of beer.
Take one down, pass it around, 82 bottles of beer on the wall.
82 bottles of beer on the wall, 82 bottles of beer.
Take one down, pass it around, 81 bottles of beer on the wall.
81 bottles of beer on the wall, 81 bottles of beer.
Take one down, pass it around, 80 bottles of beer on the wall.
80 bottles of beer on the wall, 80 bottles of beer.
Take one down, pass it around, 79 bottles of beer on the wall.
79 bottles of beer on the wall, 79 bottles of beer.
Take one down, pass it around, 78 bottles of beer on the wall.
78 bottles of beer on the wall, 78 bottles of beer.
Take one down, pass it around, 77 bottles of beer on the wall.
77 bottles of beer on the wall, 77 bottles of beer.
Take one down, pass it around, 76 bottles of beer on the wall.
76 bottles of beer on the wall, 76 bottles of beer.
Take one down, pass it around, 75 bottles of beer on the wall.
75 bottles of beer on the wall, 75 bottles of beer.
Take one down, pass it around, 74 bottles of beer on the wall.
74 bottles of beer on the wall, 74 bottles of beer.
Take one down, pass it around, 73 bottles of beer on the wall.
73 bottles of beer on the wall, 73 bottles of beer.
Take one down, pass it around, 72 bottles of beer on the wall.
72 bottles of beer on the wall, 72 bottles of beer.
Take one down, pass it around, 71 bottles of beer on the wall.
71 bottles of beer on the wall, 71 bottles of beer.
Take one down, pass it around, 70 bottles of beer on the wall.
70 bottles of beer on the wall, 70 bottles of beer.
Take one down, pass it around, 69 bottles of beer on the wall.
69 bottles of beer on the wall, 69 bottles of beer.
Take one down, pass it around, 68 bottles of beer on the wall.
68 bottles of beer on the wall, 68 bottles of beer.
Take one down, pass it around, 67 bottles of beer on the wall.
67 bottles of beer on the wall, 67 bottles of beer.
Take one down, pass it around, 66 bottles of beer on the wall.
66 bottles of beer on the wall, 66 bottles of beer.
Take one down, pass it around, 65 bottles of beer on the wall.
65 bottles of beer on the wall, 65 bottles of beer.
Take one down, pass it around, 64 bottles of beer on the wall.
64 bottles of beer on the wall, 64 bottles of beer.
Take one down, pass it around, 63 bottles of beer on the wall.
63 bottles of beer on the wall, 63 bottles of beer.
Take one down, pass it around, 62 bottles of beer on the wall.
62 bottles of beer on the wall, 62 bottles of beer.
Take one down, pass it around, 61 bottles of beer on the wall.
61 bottles of beer on the wall, 61 bottles of beer.
Take one down, pass it around, 60 bottles of beer on the wall.
60 bottles of beer on the wall, 60 bottles of beer.
Take one down, pass it around, 59 bottles of beer on the wall.
59 bottles of beer on the wall, 59 bottles of beer.
Take one down, pass it around, 58 bottles of beer on the wall.
58 bottles of beer on the wall, 58 bottles of beer.
Take one down, pass it around, 57 bottles of beer on the wall.
57 bottles of beer on the wall, 57 bottles of beer.
Take one down, pass it around, 56 bottles of beer on the wall.
56 bottles of beer on the wall, 56 bottles of beer.
Take one down, pass it around, 55 bottles of beer on the wall.
55 bottles of beer on the wall, 55 bottles of beer.
Take one down, pass it around, 54 bottles of beer on the wall.
54 bottles of beer on the wall, 54 bottles of beer.
Take one down, pass it around, 53 bottles of beer on the wall.
53 bottles of beer on the wall, 53 bottles of beer.
Take one down, pass it around, 52 bottles of beer on the wall.
52 bottles of beer on the wall, 52 bottles of beer.
Take one down, pass it around, 51 bottles of beer on the wall.
51 bottles of beer on the wall, 51 bottles of beer.
Take one down, pass it around, 50 bottles of beer on the wall.
50 bottles of beer on the wall, 50 bottles of beer.
Take one down, pass it around, 49 bottles of beer on the wall.
49 bottles of beer on the wall, 49 bottles of beer.
Take one down, pass it around, 48 bottles of beer on the wall.
48 bottles of beer on the wall, 48 bottles of beer.
Take one down, pass it around, 47 bottles of beer on the wall.
47 bottles of beer on the wall, 47 bottles of beer.
Take one down, pass it around, 46 bottles of beer on the wall.
46 bottles of beer on the wall, 46 bottles of beer.
Take one down, pass it around, 45 bottles of beer on the wall.
45 bottles of beer on the wall, 45 bottles of beer.
Take one down, pass it around, 44 bottles of beer on the wall.
44 bottles of beer on the wall, 44 bottles of beer.
Take one down, pass it around, 43 bottles of beer on the wall.
43 bottles of beer on the wall, 43 bottles of beer.
Take one down, pass it around, 42 bottles of beer on the wall.
42 bottles of beer on the wall, 42 bottles of beer.
Take one down, pass it around, 41 bottles of beer on the wall.
41 bottles of beer on the wall, 41 bottles of beer.
Take one down, pass it around, 40 bottles of beer on the wall.
40 bottles of beer on the wall, 40 bottles of beer.
Take one down, pass it around, 39 bottles of beer on the wall.
39 bottles of beer on the wall, 39 bottles of beer.
Take one down, pass it around, 38 bottles of beer on the wall.
38 bottles of beer on the wall, 38 bottles of beer.
Take one down, pass it around, 37 bottles of beer on the wall.
37 bottles of beer on the wall, 37 bottles of beer.
Take one down, pass it around, 36 bottles of beer on the wall.
36 bottles of beer on the wall, 36 bottles of beer.
Take one down, pass it around, 35 bottles of beer on the wall.
35 bottles of beer on the wall, 35 bottles of beer.
Take one down, pass it around, 34 bottles of beer on the wall.
34 bottles of beer on the wall, 34 bottles of beer.
Take one down, pass it around, 33 bottles of beer on the wall.
33 bottles of beer on the wall, 33 bottles of beer.
Take one down, pass it around, 32 bottles of beer on the wall.
32 bottles of beer on the wall, 32 bottles of beer.
Take one down, pass it around, 31 bottles of beer on the wall.
31 bottles of beer on the wall, 31 bottles of beer.
Take one down, pass it around, 30 bottles of beer on the wall.
30 bottles of beer on the wall, 30 bottles of beer.
Take one down, pass it around, 29 bottles of beer on the wall.
29 bottles of beer on the wall, 29 bottles of beer.
Take one down, pass it around, 28 bottles of beer on the wall.
28 bottles of beer on the wall, 28 bottles of beer.
Take one down, pass it around, 27 bottles of beer on the wall.
27 bottles of beer on the wall, 27 bottles of beer.
Take one down, pass it around, 26 bottles of beer on the wall.
26 bottles of beer on the wall, 26 bottles of beer.
Take one down, pass it around, 25 bottles of beer on the wall.
25 bottles of beer on the wall, 25 bottles of beer.
Take one down, pass it around, 24 bottles of beer on the wall.
24 bottles of beer on the wall, 24 bottles of beer.
Take one down, pass it around, 23 bottles of beer on the wall.
23 bottles of beer on the wall, 23 bottles of beer.
Take one down, pass it around, 22 bottles of beer on the wall.
22 bottles of beer on the wall, 22 bottles of beer.
Take one down, pass it around, 21 bottles of beer on the wall.
21 bottles of beer on the wall, 21 bottles of beer.
Take one down, pass it around, 20 bottles of beer on the wall.
20 bottles of beer on the wall, 20 bottles of beer.
Take one down, pass it around, 19 bottles of beer on the wall.
19 bottles of beer on the wall, 19 bottles of beer.
Take one down, pass it around, 18 bottles of beer on the wall.
18 bottles of beer on the wall, 18 bottles of beer.
Take one down, pass it around, 17 bottles of beer on the wall.
17 bottles of beer on the wall, 17 bottles of beer.
Take one down, pass it around, 16 bottles of beer on the wall.
16 bottles of beer on the wall, 16 bottles of beer.
Take one down, pass it around, 15 bottles of beer on the wall.
15 bottles of beer on the wall, 15 bottles of beer.
Take one down, pass it around, 14 bottles of beer on the wall.
14 bottles of beer on the wall, 14 bottles of beer.
Take one down, pass it around, 13 bottles of beer on the wall.
13 bottles of beer on the wall, 13 bottles of beer.
Take one down, pass it around, 12 bottles of beer on the wall.
12 bottles of beer on the wall, 12 bottles of beer.
Take one down, pass it around, 11 bottles of beer on the wall.
11 bottles of beer on the wall, 11 bottles of beer.
Take one down, pass it around, 10 bottles of beer on the wall.
10 bottles of beer on the wall, 10 bottles of beer.
Take one down, pass it around, 9 bottles of beer on the wall.
9 bottles of beer on the wall, 9 bottles of beer.
Take one down, pass it around, 8 bottles of beer on the wall.
8 bottles of beer on the wall, 8 bottles of beer.
Take one down, pass it around, 7 bottles of beer on the wall.
7 bottles of beer on the wall, 7 bottles of beer.
Take one down, pass it around, 6 bottles of beer on the wall.
6 bottles of beer on the wall, 6 bottles of beer.
Take one down, pass it around, 5 bottles of beer on the wall.
5 bottles of beer on the wall, 5 bottles of beer.
Take one down, pass it around, 4 bottles of beer on the wall.
4 bottles of beer on the wall, 4 bottles of beer.
Take one down, pass it around, 3 bottles of beer on the wall.
3 bottles of beer on the wall, 3 bottles of beer.
Take one down, pass it around, 2 bottles of beer on the wall.
2 bottles of beer on the wall, 2 bottles of beer.
Take one down, pass it around, 1 bottle of beer on the wall.
1 bottle of beer on the wall, 1 bottle of beer.
Take one down, pass it around, no more bottles of beer on the wall.
No more bottles of beer on the wall, no more bottles of beer.
Go to the store and buy some more, 99 bottles of beer on the wall.
-38
View File
@@ -1,38 +0,0 @@
<html>
<head>
<title>
XML encoding with Kotlin
</title>
</head>
<body>
<h1>
XML encoding with Kotlin
</h1>
<p>
this format can be used as an alternative markup to XML
</p>
<a href="https://jetbrains.com/kotlin">
Kotlin
</a>
<p>
This is some
<b>
mixed
</b>
text. For more see the
<a href="https://jetbrains.com/kotlin">
Kotlin
</a>
project
</p>
<p>
some text
</p>
<p>
Command line arguments were:
<ul>
</ul>
</p>
</body>
</html>