<commit_before>package pink.madis.agptweeter

import com.google.common.truth.Truth.assertThat
import org.junit.Test
import java.io.IOException
import kotlin.text.Charsets.UTF_8

class EmptyFetcher: Fetcher {
    override fun latestVersion(): Version? = null
}

class FixedFetcher(private val version: String): Fetcher {
    override fun latestVersion(): Version? = Version(version)
}

class FailingFetcher: Fetcher {
    override fun latestVersion(): Version? = throw IOException("Expected failure")
}

class FixedSource(
    override val fetcher: Fetcher = FixedFetcher("1.0.0"),
    override val key: String = "key",
    override val prettyName: String = "Artifact"): ArtifactSource

class CheckerTest {
    @Test
    fun testEmptyLocalVersion() {
        assertThat(isNewRemoteVersion(Version("0.0.1"), EmptyFetcher())).isTrue()
    }

    @Test
    fun testLaterLocalVersion() {
        assertThat(isNewRemoteVersion(Version("1.5.3"), FixedFetcher("2.0.0"))).isFalse()
    }

    @Test
    fun testOlderLocalVersion() {
        assertThat(isNewRemoteVersion(Version("2.0.1"), FixedFetcher("2.0.0"))).isTrue()
    }

    @Test
    fun testSameLocalVersion() {
        assertThat(isNewRemoteVersion(Version("2.0.0"), FixedFetcher("2.0.0"))).isFalse()
    }

    @Test
    fun failingRemoteResultsInException() {
        var tweet: String? = null

        try {
            checkAndTweet(FixedSource(fetcher = FailingFetcher()), MemStore(), MemStore(), { tweet = it })
        }
        catch (e: IOException) {
            assertThat(e).hasMessageThat().isEqualTo("Expected failure")
            // no tweet goes out
            assertThat(tweet).isNull()
            return
        }
        throw IllegalStateException("Expected checkAndTweet to fail")
    }

    @Test
    fun emptyRemoteResultsInException() {
        var tweet: String? = null

        try {
            checkAndTweet(FixedSource(fetcher = EmptyFetcher()), MemStore(), MemStore(), { tweet = it })
        }
        catch (e: IOException) {
            assertThat(e).hasMessageThat().isEqualTo("Did not get a proper remote version")
            // no tweet goes out
            assertThat(tweet).isNull()
            return
        }
        throw IllegalStateException("Expected checkAndTweet to fail")
    }

    @Test
    fun emptyLocalStateResultsInTweet() {
        val cache = MemStore()
        val db = MemStore()
        var tweet: String? = null

        checkAndTweet(FixedSource(), cache, db, { tweet = it })

        assertThat(tweet).isEqualTo("Artifact 1.0.0 is out!")
        // make sure that both cache and db are updated too
        assertThat(cache.read("key")).isEqualTo("1.0.0".toByteArray())
        assertThat(db.read("key")).isEqualTo("1.0.0".toByteArray())
    }

    @Test
    fun emptyCacheStateResultInNoTweet() {
        val cache = MemStore()
        val db = MemStore().apply {
            write("key", "1.0.0".toByteArray())
        }
        var tweet: String? = null

        checkAndTweet(FixedSource(), cache, db, { tweet = it })

        assertThat(tweet).isNull()
        // make sure that cache gets updated
        assertThat(cache.read("key")).isEqualTo("1.0.0".toByteArray())
    }

    @Test
    fun cacheAndDbAreUpToDate() {
        val cache = MemStore().apply {
            write("key", "1.0.0".toByteArray())
        }
        val db = MemStore().apply {
            write("key", "1.0.0".toByteArray())
        }
        var tweet: String? = null

        checkAndTweet(FixedSource(), cache, db, { tweet = it })

        assertThat(tweet).isNull()
    }

    @Test
    fun cacheAndDbAreOutOfDate() {
        val cache = MemStore().apply {
            write("key", "0.9.0".toByteArray())
        }
        val db = MemStore().apply {
            write("key", "0.9.0".toByteArray())
        }
        var tweet: String? = null

        checkAndTweet(FixedSource(), cache, db, { tweet = it })<commit_msg>Make sure that db is not hit on the most common path<commit_after>package pink.madis.agptweeter

import com.google.common.truth.Truth.assertThat
import org.junit.Test
import java.io.IOException

class EmptyFetcher: Fetcher {
    override fun latestVersion(): Version? = null
}

class FixedFetcher(private val version: String): Fetcher {
    override fun latestVersion(): Version? = Version(version)
}

class FailingFetcher: Fetcher {
    override fun latestVersion(): Version? = throw IOException("Expected failure")
}

class FixedSource(
    override val fetcher: Fetcher = FixedFetcher("1.0.0"),
    override val key: String = "key",
    override val prettyName: String = "Artifact"): ArtifactSource

val noTweet: (String)->Unit = { throw IllegalStateException("Unexpected tweet: $it") }

class CheckerTest {
    @Test
    fun testEmptyLocalVersion() {
        assertThat(isNewRemoteVersion(Version("0.0.1"), EmptyFetcher())).isTrue()
    }

    @Test
    fun testLaterLocalVersion() {
        assertThat(isNewRemoteVersion(Version("1.5.3"), FixedFetcher("2.0.0"))).isFalse()
    }

    @Test
    fun testOlderLocalVersion() {
        assertThat(isNewRemoteVersion(Version("2.0.1"), FixedFetcher("2.0.0"))).isTrue()
    }

    @Test
    fun testSameLocalVersion() {
        assertThat(isNewRemoteVersion(Version("2.0.0"), FixedFetcher("2.0.0"))).isFalse()
    }

    @Test
    fun failingRemoteResultsInException() {
        try {
            checkAndTweet(FixedSource(fetcher = FailingFetcher()), MemStore(), MemStore(), noTweet)
        }
        catch (e: IOException) {
            assertThat(e).hasMessageThat().isEqualTo("Expected failure")
            return
        }
        throw IllegalStateException("Expected checkAndTweet to fail")
    }

    @Test
    fun emptyRemoteResultsInException() {
        try {
            checkAndTweet(FixedSource(fetcher = EmptyFetcher()), MemStore(), MemStore(), noTweet)
        }
        catch (e: IOException) {
            assertThat(e).hasMessageThat().isEqualTo("Did not get a proper remote version")
            return
        }
        throw IllegalStateException("Expected checkAndTweet to fail")
    }

    @Test
    fun emptyLocalStateResultsInTweet() {
        val cache = MemStore()
        val db = MemStore()
        var tweet: String? = null

        checkAndTweet(FixedSource(), cache, db, { tweet = it })

        assertThat(tweet).isEqualTo("Artifact 1.0.0 is out!")
        // make sure that both cache and db are updated too
        assertThat(cache.read("key")).isEqualTo("1.0.0".toByteArray())
        assertThat(db.read("key")).isEqualTo("1.0.0".toByteArray())
    }

    @Test
    fun emptyCacheStateResultInNoTweet() {
        val cache = MemStore()
        val db = MemStore().apply {
            write("key", "1.0.0".toByteArray())
        }

        checkAndTweet(FixedSource(), cache, db, noTweet)

        // make sure that cache gets updated
        assertThat(cache.read("key")).isEqualTo("1.0.0".toByteArray())
    }

    @Test
    fun cacheAndDbAreUpToDate() {
        val cache = MemStore().apply {
            write("key", "1.0.0".toByteArray())
        }
        val db = object : Store {
            override fun read(key: String): ByteArray? = throw IllegalStateException("Not supposed to hit db")
            override fun write(key: String, bytes: ByteArray) = throw IllegalStateException("Not supposed to hit db")
        }

        checkAndTweet(FixedSource(), cache, db, noTweet)
    }

    @Test
    fun cacheAndDbAreOutOfDate() {
        val cache = MemStore().apply {
            write("key", "0.9.0".toByteArray())
        }
        val db = MemStore().apply {
            write("key", "0.9.0".toByteArray())
        }
        var tweet: String? = null

        checkAndTweet(FixedSource(), cache, db, { tweet = it })
{'fraction_non_alphanumeric': 0.13022113022113022, 'fraction_numerical': 0.0129315918789603, 'mean_word_length': 2.5888631090487237, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 4, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5894677', 'n_tokens_mistral': 2323, 'n_tokens_neox': 2304, 'n_words': 508}