This commit is contained in:
Ralf Comtesse 2025-10-06 14:52:31 +00:00 committed by GitHub
commit 4428e34f2a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
13 changed files with 156 additions and 25 deletions

13
scala/.gitignore vendored
View File

@ -1,4 +1,5 @@
/bin/
lib/
# OSX Finder
.DS_Store
@ -6,6 +7,17 @@
# IntelliJ
.idea
*.iml
.bsp
.bloop
#vscode
.vscode
.metals
.scala-build
metals.sbt
# Eclipse
.worksheet
@ -17,3 +29,4 @@
.classpath
target/
approvaltests/gildedrose.testresult.txt

View File

@ -20,3 +20,26 @@ sbt "run 10"
``` cmd
sbt test
```
## Run approval tests
The approval test can be found in the src/test/scala/GildedRoseApprovalTest.scala. It uses the approval test framework from https://github.com/approvals/ApprovalTests.Java.
The initial run will be a failing test and suggests an output to accept as the first approved version. Each subsequent run of the test will succeed until the output from the test changes.
To approve a new version, simply accept some or all diffs between the existing approved files and the newly generated output.
Approval tests are part of the test suite triggered by "sbt test".
``` cmd
sbt test
```
## Run texttest version of approval tests
To run the texttest version, first edit the texttest configuration file. It contains to sections for scala that need to be uncommented.
* the executable and interpreter lines to run texttest_rig.py to trigger an sbt run
* the four lines in the run_dependent_text section to ignore sbt's info and success lines in the output.
Be aware that running the texttest version is somewhat slow since starting sbt takes some time.

View File

@ -1,4 +1,4 @@
val scala3Version = "3.6.4"
val scala3Version = "3.7.3"
lazy val root = project
.in(file("."))
@ -6,6 +6,10 @@ lazy val root = project
name := "GildedRose",
version := "1.0",
scalaVersion := scala3Version,
libraryDependencies += "org.scalatest" %% "scalatest" % "3.2.19" % "test"
libraryDependencies ++= Seq(
"org.scalatest" %% "scalatest" % "3.2.19" % Test,
"com.approvaltests" % "approvaltests" % "25.4.3" % Test,
"com.github.sbt.junit" % "jupiter-interface" % "0.15.1" % Test
),
testOptions += Tests.Argument(TestFrameworks.JUnit)
)

View File

@ -1,2 +0,0 @@
project/
target/

View File

@ -1 +1 @@
sbt.version=1.10.10
sbt.version=1.11.6

View File

@ -0,0 +1 @@
addSbtPlugin("com.github.sbt.junit" % "sbt-jupiter-interface" % "0.15.1")

View File

@ -1,5 +1,5 @@
package com.gildedrose
class Item(val name: String, var sellIn: Int, var quality: Int) {
case class Item(name: String, var sellIn: Int, var quality: Int) {
}

View File

@ -3,16 +3,16 @@ package com.gildedrose
object Main {
def main(args: Array[String]): Unit = {
val items = Array[Item](
new Item("+5 Dexterity Vest", 10, 20),
new Item("Aged Brie", 2, 0),
new Item("Elixir of the Mongoose", 5, 7),
new Item("Sulfuras, Hand of Ragnaros", 0, 80),
new Item("Sulfuras, Hand of Ragnaros", -1, 80),
new Item("Backstage passes to a TAFKAL80ETC concert", 15, 20),
new Item("Backstage passes to a TAFKAL80ETC concert", 10, 49),
new Item("Backstage passes to a TAFKAL80ETC concert", 5, 49),
Item("+5 Dexterity Vest", 10, 20),
Item("Aged Brie", 2, 0),
Item("Elixir of the Mongoose", 5, 7),
Item("Sulfuras, Hand of Ragnaros", 0, 80),
Item("Sulfuras, Hand of Ragnaros", -1, 80),
Item("Backstage passes to a TAFKAL80ETC concert", 15, 20),
Item("Backstage passes to a TAFKAL80ETC concert", 10, 49),
Item("Backstage passes to a TAFKAL80ETC concert", 5, 49),
// this conjured item does not work properly yet
new Item("Conjured Mana Cake", 3, 6)
Item("Conjured Mana Cake", 3, 6)
)
val app = new GildedRose(items)

View File

@ -0,0 +1,38 @@
package com.gildedrose
import org.approvaltests.Approvals
import org.approvaltests.reporters.DiffReporter
import org.approvaltests.reporters.UseReporter
import org.junit.jupiter.api.Test
import java.io.ByteArrayInputStream
import java.io.ByteArrayOutputStream
import java.io.PrintStream
@UseReporter(Array(classOf[DiffReporter]))
class GildedRoseApprovalTest {
@Test
def foo(): Unit = {
val items: Array[Item] = Array(Item("foo", 0, 0))
val app: GildedRose = new GildedRose(items)
app.updateQuality()
Approvals.verifyAll("Items", items)
}
@Test
def thirtyDays(): Unit = {
val fakeoutput: ByteArrayOutputStream = new ByteArrayOutputStream()
System.setOut(new PrintStream(fakeoutput))
System.setIn(new ByteArrayInputStream("a\n".getBytes()))
val args: Array[String] = Array("30")
TexttestFixture.main(args)
val output: String = fakeoutput.toString()
Approvals.verify(output)
}
}

View File

@ -5,7 +5,7 @@ import org.scalatest.matchers.should.Matchers
class GildedRoseTest extends AnyFlatSpec with Matchers {
it should "foo" in {
val items = Array[Item](new Item("foo", 0, 0))
val items = Array[Item](Item("foo", 0, 0))
val app = new GildedRose(items)
app.updateQuality()
app.items(0).name should equal("fixme")

View File

@ -0,0 +1,34 @@
package com.gildedrose
object TexttestFixture {
def main(args: Array[String]): Unit = {
System.out.println("OMGHAI!")
val items = Array[Item](
Item("+5 Dexterity Vest", 10, 20),
Item("Aged Brie", 2, 0),
Item("Elixir of the Mongoose", 5, 7),
Item("Sulfuras, Hand of Ragnaros", 0, 80),
Item("Sulfuras, Hand of Ragnaros", -1, 80),
Item("Backstage passes to a TAFKAL80ETC concert", 15, 20),
Item("Backstage passes to a TAFKAL80ETC concert", 10, 49),
Item("Backstage passes to a TAFKAL80ETC concert", 5, 49), // this conjured item does not work properly yet
Item("Conjured Mana Cake", 3, 6)
)
val app = new GildedRose(items)
var days = 2
if (args.nonEmpty) days = args(0).toInt + 1
for (i <- 0 until days) {
System.out.println("-------- day " + i + " --------")
System.out.println("name, sellIn, quality")
for (item <- items) {
System.out.println(s"${item.name}, ${item.sellIn}, ${item.quality}")
}
System.out.println()
app.updateQuality()
}
}
}

14
scala/texttest_rig.py Normal file
View File

@ -0,0 +1,14 @@
#!/usr/bin/env python
"""
This script uses sbt to execute the TexttestFixture.
It is designed to be used by TextTest and specified in the file 'texttests/config.gr' in this repo.
It is more convenient for TextTest to use since Gradle needs
several arguments in addition to the one the TextTest fixture needs.
"""
import os
import subprocess
import sys
args = " ".join(sys.argv[1:])
TEXTTEST_HOME = os.environ.get("TEXTTEST_HOME", os.getcwd())
subprocess.run(f"""(cd {TEXTTEST_HOME}/scala/; sbt -warn "Test / runMain com.gildedrose.TexttestFixture {args}") """, shell=True)

View File

@ -70,4 +70,10 @@ interpreter:ruby
# Settings for the Odin version
#executable:${TEXTTEST_HOME}/odin/gilded_rose<include your OS executable extension here>
# Settings for the scala version using sbt wrapped in a python script
# executable:${TEXTTEST_HOME}/scala/texttest_rig.py
# interpreter:python
filename_convention_scheme:standard