Repository: JetBrains/kotlin
File: compiler/tests/org/jetbrains/kotlin/cli/JarOutputTest.kt (Kotlin)

Code before:

        assertNoModuleInfoClass(jar)
    }

    private fun assertAllTimestampsAreReset(jar: File) {
        val zis = JarInputStream(FileInputStream(jar))
        var entry: ZipEntry? = zis.nextEntry
        while (entry != null) {
            assertEquals(entry.time, DOS_EPOCH, "$entry timestamp should be reset")
            entry = zis.nextEntry
        }
    }

    private fun assertNoTimestampsAreReset(jar: File) {
        val zis = JarInputStream(FileInputStream(jar))
        var entry: ZipEntry? = zis.nextEntry
        while (entry != null) {
            assertNotEquals(entry.time, DOS_EPOCH, "$entry timestamp should not be reset")
            entry = zis.nextEntry
        }
    }

    private fun assertNoModuleInfoClass(jar: File) {
        val zis = JarInputStream(FileInputStream(jar))
        var entry: ZipEntry? = zis.nextEntry
        while (entry != null) {
            assertNotEquals(
                "module-info.class", entry.name.substringAfterLast("/"),
                "$entry is expected to be excluded from the resulting jar"
            )
            entry = zis.nextEntry
        }
    }
}


Review comment (suggestion):
I think we can iterate over all entries a bit easier with `for (entry in JarFile(jar).entries())`. Consider maybe improving the code of the other test functions in this file similarly as well

Code after:
/*
 * Copyright 2010-2020 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.cli

import java.io.File
import kotlin.test.assertEquals
import kotlin.test.assertNotEquals
import org.jetbrains.kotlin.cli.jvm.K2JVMCompiler
import org.jetbrains.kotlin.cli.jvm.compiler.CompileEnvironmentUtil.DOS_EPOCH
import org.jetbrains.kotlin.test.TestCaseWithTmpdir
import java.util.jar.JarFile

class JarOutputTest : TestCaseWithTmpdir() {

    fun testDeterministicOutput() {
        val fooKt = tmpdir.resolve("foo.kt").also {
            it.writeText("class Foo")
        }

        val firstJar = tmpdir.resolve("first.jar")
        AbstractCliTest.executeCompilerGrabOutput(
            K2JVMCompiler(),
            listOf(fooKt.path, "-d", firstJar.path, "-include-runtime"))

        val secondJar = tmpdir.resolve("second.jar")
        AbstractCliTest.executeCompilerGrabOutput(
            K2JVMCompiler(),
            listOf(fooKt.path, "-d", secondJar.path, "-include-runtime"))

        assertEquals(
            firstJar.readBytes().toList(),
            secondJar.readBytes().toList(),
            "jar contents should be identical if compiler command and inputs are the same")
        assertAllTimestampsAreReset(firstJar)
        assertAllTimestampsAreReset(secondJar)
    }

    fun testNoResetJarTimestamps() {
        val fooKt = tmpdir.resolve("foo.kt").also {
            it.writeText("class Foo")
        }
        val jar = tmpdir.resolve("jarWithTimestamps.jar")
        AbstractCliTest.executeCompilerGrabOutput(
            K2JVMCompiler(),
            listOf(fooKt.path, "-d", jar.path, "-include-runtime", "-Xno-reset-jar-timestamps"))

        assertNoTimestampsAreReset(jar)
    }

    /**
     *  KT-44078
     */
    fun testNoModuleInfoClass() {
        val fooKt = tmpdir.resolve("foo.kt").also {
            it.writeText("class Foo")
        }
        val jar = tmpdir.resolve("jarWithoutModuleInfoClass.jar")
        AbstractCliTest.executeCompilerGrabOutput(
            K2JVMCompiler(),
            listOf(fooKt.path, "-d", jar.path, "-include-runtime")
        )

        assertNoModuleInfoClass(jar)
    }

    private fun assertAllTimestampsAreReset(jar: File) {
        for (entry in JarFile(jar).entries()) {
            assertEquals(entry.time, DOS_EPOCH, "$entry timestamp should be reset")
        }
    }

    private fun assertNoTimestampsAreReset(jar: File) {
        for (entry in JarFile(jar).entries()) {
            assertNotEquals(entry.time, DOS_EPOCH, "$entry timestamp should not be reset")
        }
    }

    private fun assertNoModuleInfoClass(jar: File) {
        for (entry in JarFile(jar).entries()) {
            assertNotEquals(
                "module-info.class", entry.name.substringAfterLast("/"),
                "$entry is expected to be excluded from the resulting jar"
            )
        }
    }
}