From 7351731e20206a0d880a15e3aafa4a2e36b9c3fc Mon Sep 17 00:00:00 2001 From: Bruce Eckel Date: Mon, 22 Jul 2024 10:57:27 -0600 Subject: [PATCH] Changed Material/Tools example to compact form #bruce #time 30m --- Chapters/05_Testing.md | 47 +++++--------- .../{birdhouse => basic}/BasicTest.scala | 2 +- .../BirdHouse.scala | 63 ++++--------------- 3 files changed, 26 insertions(+), 86 deletions(-) rename src/main/scala/{birdhouse => basic}/BasicTest.scala (98%) rename src/main/scala/{birdhouse => experiments}/BirdHouse.scala (51%) diff --git a/Chapters/05_Testing.md b/Chapters/05_Testing.md index 26b0653e..8106c3dd 100644 --- a/Chapters/05_Testing.md +++ b/Chapters/05_Testing.md @@ -182,58 +182,39 @@ An Effect Oriented test library produces the best of both worlds by generating t ## Birdhouse Factory Suppose you want to build birdhouses as fast as possible, and you have a choice of materials for building them. -The `Material`s have different levels of `brittleness` so some `Tool`s might break some `Material`s. -We want to test different `Material`s with different combinations of `Tool`s. -All `Material`s and `Tool`s have `ZLayer` services, so we easily swap them around during testing. +The `Material`s have different levels of `brittleness` so some tools might break some `Material`s. +We want to test different `Material`s with different combinations of tools. +All `Material`s and tools have `ZLayer` services, so we easily swap them around during testing. `Wood` and `Plastic` are `Material`s with different `brittleness` factors: ```scala 3 mdoc:silent testzio import zio.* -trait Material: - val brittleness: Int - -case class Wood() extends Material: - val brittleness = 5 - -case class Plastic() extends Material: - val brittleness = 10 +class Material(val brittleness: Int) object Material: - val wood = ZLayer.succeed(Wood()) - val plastic = ZLayer.succeed(Plastic()) + val wood = ZLayer.succeed(Material(brittleness = 5)) + val plastic = ZLayer.succeed(Material(brittleness = 10)) ``` -We define `Tool`s in a similar way. -Each type of `Tool` has an `intensity` that relates it to `Material.brittleness`. +Different types of `Saw` and `Nailer` each have an `intensity` that relates it to `Material.brittleness`. ```scala 3 mdoc:silent testzio import zio.* import zio.Console.* -trait Tool: - val intensity: Int - -trait Saw extends Tool -case class HandSaw() extends Saw: - val intensity = 4 -case class RoboSaw() extends Saw: - val intensity = 8 +class Saw(val intensity: Int) object Saw: - val hand = ZLayer.succeed(HandSaw()) - val robotic = ZLayer.succeed(RoboSaw()) + val hand = ZLayer.succeed(Saw(intensity = 4)) + val robotic = ZLayer.succeed(Saw(intensity = 8)) -trait Nailer extends Tool -case class Hammer() extends Nailer: - val intensity = 4 -case class RoboNailer() extends Nailer: - val intensity = 11 +class Nailer(val intensity: Int) object Nailer: - val hand = ZLayer.succeed(Hammer()) - val robotic = ZLayer.succeed(RoboNailer()) + val hand = ZLayer.succeed(Nailer(intensity = 4)) + val robotic = ZLayer.succeed(Nailer(intensity = 11)) ```` The test takes a `Material` and checks it against a `Saw` and a `Nailer`: @@ -297,7 +278,7 @@ It gives all the information you need to see exactly what's happening. We've only shown a few combinations here. As an exercise, try adding others. -Then add a new `Material` called `Metal`, and a new `Tool` category called `Power`, with an additional type `Drill`. +Then add a new `Material` called `Metal`, and a new tool category called `Power`, with an additional type `Drill`. ## Testing Effects diff --git a/src/main/scala/birdhouse/BasicTest.scala b/src/main/scala/basic/BasicTest.scala similarity index 98% rename from src/main/scala/birdhouse/BasicTest.scala rename to src/main/scala/basic/BasicTest.scala index 510b7c6e..e48b7733 100644 --- a/src/main/scala/birdhouse/BasicTest.scala +++ b/src/main/scala/basic/BasicTest.scala @@ -1,4 +1,4 @@ -package birdhouse +package basic import zio.* import zio.direct.* diff --git a/src/main/scala/birdhouse/BirdHouse.scala b/src/main/scala/experiments/BirdHouse.scala similarity index 51% rename from src/main/scala/birdhouse/BirdHouse.scala rename to src/main/scala/experiments/BirdHouse.scala index 039550ae..989a54fd 100644 --- a/src/main/scala/birdhouse/BirdHouse.scala +++ b/src/main/scala/experiments/BirdHouse.scala @@ -1,68 +1,27 @@ -package birdhouse +package experiments import zio.* -trait Material: - val brittleness: Int - -case class Wood() extends Material: - val brittleness = 5 - -case class Plastic() extends Material: - val brittleness = 10 +class Material(val brittleness: Int) object Material: - val wood = ZLayer.succeed(Wood()) - val plastic = ZLayer.succeed(Plastic()) - -import zio.Console.* - -trait Tool: - val action: String - val intensity: Int - val use = - printLine( - s"$this $action, intensity $intensity" - ) + val wood = ZLayer.succeed(Material(brittleness = 5)) + val plastic = ZLayer.succeed(Material(brittleness = 10)) -trait Saw extends Tool: - val action = "sawing" -case class HandSaw() extends Saw: - val intensity = 4 -case class RoboSaw() extends Saw: - val intensity = 8 +class Saw(val intensity: Int) object Saw: - val hand = ZLayer.succeed(HandSaw()) - val robotic = ZLayer.succeed(RoboSaw()) + val hand = ZLayer.succeed(Saw(intensity = 4)) + val robotic = ZLayer.succeed(Saw(intensity = 8)) -trait Nailer extends Tool: - val action = "nailing" -case class Hammer() extends Nailer: - val intensity = 4 -case class RoboNailer() extends Nailer: - val intensity = 11 +class Nailer(val intensity: Int) object Nailer: - val hand = ZLayer.succeed(Hammer()) - val robotic = ZLayer.succeed(RoboNailer()) - -// Just checking - -import zio.direct.* - -object UseTools extends ZIOAppDefault: - def run = - defer: - List( - Hammer(), - RoboNailer(), - HandSaw(), - RoboSaw(), - ).foreach(_.use.run) -// end checking + val hand = ZLayer.succeed(Nailer(intensity = 4)) + val robotic = ZLayer.succeed(Nailer(intensity = 11)) import zio.test.* +import zio.direct.* val testToolWithMaterial = defer: