Skip to content

Commit a61a16e

Browse files
committed
feat: download snippets and create test file
1 parent 8bdd165 commit a61a16e

File tree

3 files changed

+93
-0
lines changed

3 files changed

+93
-0
lines changed

src/main/kotlin/dev/mtib/aoc/AocRunner.kt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,14 @@ suspend fun runDay(day: Day) {
120120
return
121121
}
122122

123+
if (System.getenv("CI").isNullOrBlank()) {
124+
try {
125+
aocDay.createTestFile()
126+
} catch (e: Exception) {
127+
logger.error(e = e, year = day.year, day = day.toInt()) { "failed to create test file" }
128+
}
129+
}
130+
123131
mapOf(
124132
::runResults to "solving puzzles",
125133
::benchmark to "running benchmarks",
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
package dev.mtib.aoc.aoc24.days
2+
3+
import dev.mtib.aoc.day.AocDay
4+
5+
object Day7: AocDay(2024, 7) {
6+
override suspend fun part1(): Any {
7+
return super.part1()
8+
}
9+
10+
override suspend fun part2(): Any {
11+
return super.part2()
12+
}
13+
}

src/main/kotlin/dev/mtib/aoc/day/AocDay.kt

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ import dev.mtib.aoc.util.Year
1515
import dev.mtib.aoc.util.styleResult
1616
import kotlinx.coroutines.CoroutineDispatcher
1717
import kotlinx.coroutines.Dispatchers
18+
import kotlinx.serialization.encodeToString
19+
import kotlinx.serialization.json.Json
1820
import okhttp3.OkHttpClient
1921
import okhttp3.Request
2022
import org.reflections.Reflections
@@ -178,6 +180,76 @@ open class AocDay(
178180
val waitDuration = (releaseTime.toInstant().toEpochMilli() - System.currentTimeMillis()).milliseconds
179181
}
180182

183+
fun createTestFile() {
184+
if (year < 2024) {
185+
return
186+
}
187+
if (releaseTime.isAfter(ZonedDateTime.now())) {
188+
return
189+
}
190+
val token = System.getenv("SESSION")
191+
if (token.isNullOrBlank()) {
192+
return
193+
}
194+
val outPath = Path("src/test/kotlin/dev/mtib/aoc/aoc${year%100}/days/Day${day}Test.kt")
195+
if (outPath.exists()) {
196+
return
197+
}
198+
val request = Request.Builder()
199+
.url("https://adventofcode.com/$year/day/$day")
200+
.get()
201+
.addHeader("Cookie", "session=$token")
202+
.build()
203+
val client = OkHttpClient()
204+
val response = client.newCall(request).execute()
205+
val body = response.body!!.string()
206+
val codeRegex = Regex("""<pre><code>(.*?)</code></pre>""", RegexOption.DOT_MATCHES_ALL)
207+
val codeSnippets = codeRegex.findAll(body)
208+
.map { it.groupValues[1].replace("&lt;", "<").replace("&gt;", ">") }
209+
.filterNot { it.contains("<em>") }
210+
.distinct()
211+
212+
logger.log(identity) { "creating ${outPath.fileName} with code snippets" }
213+
214+
outPath.writeText(buildString {
215+
appendLine("""
216+
package dev.mtib.aoc.aoc24.days
217+
218+
import io.kotest.core.spec.style.FunSpec
219+
220+
class Day${day}Test : FunSpec({
221+
""".trimIndent())
222+
codeSnippets.forEachIndexed { index, code ->
223+
appendLine(
224+
" val snippet${index} = \"\"\"\n${
225+
code.trimEnd().lines().joinToString("\n") { " ".repeat(8) + it }
226+
}\n \"\"\".trimIndent()"
227+
)
228+
}
229+
appendLine("""
230+
context("part1") {
231+
test("doesn't throw") {
232+
try {
233+
Day${day}.part1()
234+
} catch (e: NotImplementedError) {
235+
// Ignore allowed exception
236+
}
237+
}
238+
}
239+
context("part2") {
240+
test("doesn't throw") {
241+
try {
242+
Day${day}.part2()
243+
} catch (e: NotImplementedError) {
244+
// Ignore allowed exception
245+
}
246+
}
247+
}
248+
})
249+
""".trimIndent())
250+
})
251+
}
252+
181253
suspend fun <T> withInput(input: String, block: suspend AocDay.() -> T): T {
182254
fakedInput = input.some()
183255
return this.block().also { fakedInput = None }

0 commit comments

Comments
 (0)