Skip to content

Commit

Permalink
Add WASM ShoppingCart test
Browse files Browse the repository at this point in the history
  • Loading branch information
danieletorelli committed Aug 19, 2024
1 parent 212a2b8 commit efcec3d
Show file tree
Hide file tree
Showing 7 changed files with 155 additions and 0 deletions.
7 changes: 7 additions & 0 deletions src/sbt-test/wasm/shopping-cart/build.sbt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
ThisBuild / version := "0.1"
ThisBuild / scalaVersion := "2.13.13"
ThisBuild / crossScalaVersions += "2.12.19"

lazy val root = (project in file("."))
.enablePlugins(WasmComponentPlugin)
.settings(wasmComponentPackageName := "example")
10 changes: 10 additions & 0 deletions src/sbt-test/wasm/shopping-cart/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"scripts": {
"build": "jco componentize -w wit -o target/dist/main.wasm target/dist/main.js",
"componentize": "npm run build"
},
"devDependencies": {
"@bytecodealliance/componentize-js": "0.10.2",
"@bytecodealliance/jco": "1.4.0"
}
}
1 change: 1 addition & 0 deletions src/sbt-test/wasm/shopping-cart/project/build.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
sbt.version=1.9.9
7 changes: 7 additions & 0 deletions src/sbt-test/wasm/shopping-cart/project/plugins.sbt
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
sys.props.get("plugin.version") match {
case Some(version) =>
addSbtPlugin("cloud.golem" % "sbt-wasm-component" % version)
case _ =>
sys.error("""|The system property 'plugin.version' is not defined.
|Specify this property using the scriptedLaunchOpts -D.""".stripMargin)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
package example

final case class State(userId: String, items: List[ProductItem]) { self =>
def withUserId(userId: String): State = self.copy(userId = userId)

def addItem(item: ProductItem): State = self.copy(items = self.items :+ item)

def removeItem(productId: String): State = self.copy(items = self.items.filterNot(_.productId == productId))

def updateItemQuantity(productId: String, quantity: Integer): State =
self.copy(items = self.items.map { item =>
if (item.productId == productId) ProductItem(item.productId, item.name, item.price, quantity)
else item
})

def clear: State = self.copy(items = List.empty)
}
object State {
val empty = State(userId = "", items = List.empty)
}

@cloud.golem.WitExport
object ShoppingCart extends Api { self =>
private var state = State.empty

def initializeCart(userId: String): WitResult[String, String] = {
println(s"Initializing cart for user $userId")
if (math.random() > 0.1) {
state = state.withUserId(userId)
WitResult.ok(userId)
} else WitResult.err("Error while initializing cart")
}

def addItem(item: ProductItem): Unit = {
println(s"Adding item to the cart of user ${state.userId}")
state = state.addItem(item)
}

def removeItem(productId: String): Unit = {
println(s"Removing item with product ID $productId from the cart of user ${state.userId}")
state = state.removeItem(productId)
}

def updateItemQuantity(productId: String, quantity: Integer): Unit = {
println(s"Updating quantity of item with product ID $productId to $quantity in the cart of user ${state.userId}")

state = state.updateItemQuantity(productId, quantity)
}

def checkout(): CheckoutResult = {
def reserveInventory(): Either[String, Unit] =
if (math.random() < 0.1) Left("Inventory not available") else Right(())

def chargeCreditCard(): Either[String, Unit] = Right(())

def generateOrder(): String = "238738674"

def dispatchOrder(): Either[String, Unit] = Right(())

def clearState(): Unit = state = state.clear

val result =
for {
_ <- reserveInventory()
_ <- chargeCreditCard()
orderId = generateOrder()
_ <- dispatchOrder()
_ = clearState()
_ = println(s"Checkout for order $orderId")
} yield OrderConfirmation(orderId)

result match {
case Right(orderConfirmation) => CheckoutResult.success(orderConfirmation)
case Left(error) => CheckoutResult.error(error)
}
}

def getCartContents(): WitList[ProductItem] = {
println(s"Getting cart contents for user ${state.userId}")
WitList.fromList(state.items)
}

def getFirstItem(): WitOption[ProductItem] = {
println(s"Getting first item for user ${state.userId}")
WitOption.fromOption(state.items.headOption)
}
}
6 changes: 6 additions & 0 deletions src/sbt-test/wasm/shopping-cart/test
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
> +clean
$ exec cargo install golem-scalajs-wit-bindgen
> +wasmComponent
$ exists target/dist/main.js
$ exists target/dist/main.js.map
$ exists target/dist/main.wasm
37 changes: 37 additions & 0 deletions src/sbt-test/wasm/shopping-cart/wit/example.wit
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
package pack:name;

interface api {
record product-item {
product-id: string,
name: string,
price: float32,
quantity: u32,
}

record order-confirmation {
order-id: string,
}

variant checkout-result {
error(string),
success(order-confirmation),
}

initialize-cart: func(user-id: string) -> result<string, string>;

add-item: func(item: product-item) -> ();

remove-item: func(product-id: string) -> ();

update-item-quantity: func(product-id: string, quantity: u32) -> ();

checkout: func() -> checkout-result;

get-cart-contents: func() -> list<product-item>;

get-first-item: func() -> option<product-item>;
}

world main {
export api;
}

0 comments on commit efcec3d

Please sign in to comment.