blob: c9e3c72eed890894649f74df056f19d42bf48e6c [file] [log] [blame]
/*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* 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 com.facebook.ktfmt
import com.google.common.truth.Truth.assertThat
import java.io.ByteArrayOutputStream
import java.io.File
import java.io.PrintStream
import java.lang.IllegalStateException
import java.util.concurrent.ForkJoinPool
import org.junit.After
import org.junit.Assert.fail
import org.junit.Test
import org.junit.runner.RunWith
import org.junit.runners.JUnit4
@Suppress("FunctionNaming")
@RunWith(JUnit4::class)
class MainKtTest {
private val root = createTempDir()
@After
fun tearDown() {
root.deleteRecursively()
}
/**
* Scenario: someone _really_ wants to format this file, regardless of its extension. When a
* single argument file is given, it is used as is without filtering by extension.
*/
@Test
fun `expandArgsToFileNames - single file arg is used as is`() {
val fooBar = root.resolve("foo.bar")
fooBar.writeText("hi")
assertThat(expandArgsToFileNames(listOf(fooBar.toString()))).containsExactly(fooBar)
}
@Test
fun `expandArgsToFileNames - single arg which is not a file is not returned`() {
val fooBar = root.resolve("foo.bar")
assertThat(expandArgsToFileNames(listOf(fooBar.toString()))).isEmpty()
}
@Test
fun `expandArgsToFileNames - single arg which is a directory is resolved to its recursively contained kt files`() {
val dir = root.resolve("dir")
dir.mkdirs()
val foo = dir.resolve("foo.kt")
foo.writeText("")
val bar = dir.resolve("bar.kt")
bar.writeText("")
assertThat(expandArgsToFileNames(listOf(dir.toString()))).containsExactly(foo, bar)
}
@Test
fun `expandArgsToFileNames - multiple directory args are resolved to their recursively contained kt files`() {
val dir1 = root.resolve("dir1")
dir1.mkdirs()
val foo1 = dir1.resolve("foo1.kt")
foo1.writeText("")
val bar1 = dir1.resolve("bar1.kt")
bar1.writeText("")
val dir2 = root.resolve("dir2")
dir1.mkdirs()
val foo2 = dir1.resolve("foo2.kt")
foo2.writeText("")
val bar2 = dir1.resolve("bar2.kt")
bar2.writeText("")
assertThat(expandArgsToFileNames(listOf(dir1.toString(), dir2.toString())))
.containsExactly(foo1, bar1, foo2, bar2)
}
@Test
fun `expandArgsToFileNames - a dash is an error`() {
try {
expandArgsToFileNames(listOf(root.resolve("foo.bar").toString(), File("-").toString()))
fail("expected exception, but nothing was thrown")
} catch (e: IllegalStateException) {
assertThat(e.message).contains("Error")
}
}
@Test
fun `formatStdin formats an InputStream`() {
val code = "fun f1 ( ) : Int = 0"
val output = ByteArrayOutputStream()
Main(code.byteInputStream(), PrintStream(output), PrintStream(output), arrayOf()).formatStdin()
val expected = """fun f1(): Int = 0
|""".trimMargin()
assertThat(output.toString("UTF-8")).isEqualTo(expected)
}
@Test
fun `Parsing errors are reported (stdin)`() {
val code = "fun f1 ( "
val err = ByteArrayOutputStream()
val returnValue =
Main(
code.byteInputStream(),
PrintStream(ByteArrayOutputStream()),
PrintStream(err),
arrayOf())
.formatStdin()
assertThat(returnValue).isFalse()
assertThat(err.toString("UTF-8")).startsWith("<stdin>:1:14: error: ")
}
@Test
fun `Parsing errors are reported (file)`() {
val fooBar = root.resolve("foo.kt")
fooBar.writeText("fun f1 ( ")
val err = ByteArrayOutputStream()
val returnValue =
Main(
"".byteInputStream(),
PrintStream(ByteArrayOutputStream()),
PrintStream(err),
arrayOf(fooBar.toString()))
.run()
assertThat(returnValue).isEqualTo(1)
assertThat(err.toString("UTF-8")).contains("foo.kt:1:14: error: ")
}
@Test
fun `all files in args are processed, even if one of them has an error`() {
val file1 = root.resolve("file1.kt")
val file2Broken = root.resolve("file2.kt")
val file3 = root.resolve("file3.kt")
file1.writeText("fun f1 () ")
file2Broken.writeText("fun f1 ( ")
file3.writeText("fun f1 () ")
val err = ByteArrayOutputStream()
// Make Main() process files serially.
val forkJoinPool = ForkJoinPool(1)
val returnValue: Int =
forkJoinPool
.submit<Int> {
Main(
"".byteInputStream(),
PrintStream(ByteArrayOutputStream()),
PrintStream(err),
arrayOf(file1.toString(), file2Broken.toString(), file3.toString()))
.run()
}
.get()
assertThat(returnValue).isEqualTo(1)
assertThat(err.toString("UTF-8")).contains("Done formatting $file1")
assertThat(err.toString("UTF-8")).contains("file2.kt:1:14: error: ")
assertThat(err.toString("UTF-8")).contains("Done formatting $file3")
}
@Test
fun `dropbox-style is passed to formatter (file)`() {
val code =
"""fun f() {
for (child in
node.next.next.next.next.next.next.next.next.next.next.next.next.next.next.data()) {
println(child)
}
}
"""
val fooBar = root.resolve("foo.kt")
fooBar.writeText(code)
val output = ByteArrayOutputStream()
Main(
"".byteInputStream(),
PrintStream(output),
PrintStream(output),
arrayOf("--dropbox-style", fooBar.toString()))
.run()
assertThat(fooBar.readText()).isEqualTo(code)
}
@Test
fun `dropbox-style is passed to formatter (stdin)`() {
val code =
"""fun f() {
for (child in
node.next.next.next.next.next.next.next.next.next.next.next.next.next.next.data()) {
println(child)
}
}
"""
val output = ByteArrayOutputStream()
Main(
code.byteInputStream(),
PrintStream(output),
PrintStream(output),
arrayOf("--dropbox-style", "-"))
.run()
assertThat(output.toString("UTF-8")).isEqualTo(code)
}
@Test
fun `expandArgsToFileNames - resolves 'kt' and 'kts' filenames only (recursively)`() {
val f1 = root.resolve("1.kt")
val f2 = root.resolve("2.kt")
val f3 = root.resolve("3")
val f4 = root.resolve("4.dummyext")
val f5 = root.resolve("5.kts")
val dir = root.resolve("foo")
dir.mkdirs()
val f6 = root.resolve("foo/1.kt")
val f7 = root.resolve("foo/2.kts")
val f8 = root.resolve("foo/3.dummyext")
val files = listOf(f1, f2, f3, f4, f5, f6, f7, f8)
for (f in files) {
f.createNewFile()
}
assertThat(expandArgsToFileNames(files.map { it.toString() }))
.containsExactly(f1, f2, f5, f6, f7)
}
}