|
|
|
@ -1,10 +1,10 @@ |
|
|
|
package com.github.mgifos.workouts.model |
|
|
|
package com.github.mgifos.workouts.model |
|
|
|
|
|
|
|
|
|
|
|
import com.github.mgifos.workouts.model.DistanceUnits._ |
|
|
|
import com.github.mgifos.workouts.model.DistanceUnits._ |
|
|
|
import org.scalatest.{ FlatSpec, Matchers } |
|
|
|
import org.scalatest.{ Matchers, WordSpec } |
|
|
|
import play.api.libs.json.Json |
|
|
|
import play.api.libs.json.Json |
|
|
|
|
|
|
|
|
|
|
|
class WorkoutSpec extends FlatSpec with Matchers { |
|
|
|
class WorkoutSpec extends WordSpec with Matchers { |
|
|
|
|
|
|
|
|
|
|
|
implicit val msys = MeasurementSystems.metric |
|
|
|
implicit val msys = MeasurementSystems.metric |
|
|
|
|
|
|
|
|
|
|
|
@ -18,47 +18,71 @@ class WorkoutSpec extends FlatSpec with Matchers { |
|
|
|
*/ |
|
|
|
*/ |
|
|
|
val testWO = "running: run-fast\n- warmup: 10:00\n- repeat: 2\n - run: 1500m @ 4:30-5:00\n - recover: 01:30 @ z2\n- cooldown: lap-button" |
|
|
|
val testWO = "running: run-fast\n- warmup: 10:00\n- repeat: 2\n - run: 1500m @ 4:30-5:00\n - recover: 01:30 @ z2\n- cooldown: lap-button" |
|
|
|
|
|
|
|
|
|
|
|
"Workout" should "parse correctly" in { |
|
|
|
"Workout parser should" should { |
|
|
|
Workout.parseDef("") should be('left) |
|
|
|
|
|
|
|
Workout.parseDef("running") should be('left) |
|
|
|
|
|
|
|
Workout.parseDef("running:") should be('left) |
|
|
|
|
|
|
|
Workout.parseDef("running !") should be('left) |
|
|
|
|
|
|
|
Workout.parseDef("running run-fast") should be('left) |
|
|
|
|
|
|
|
Workout.parseDef(" running: run-fast") should be('left) |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
Workout.parseDef(testWO) should be( |
|
|
|
"parse notes correctly" in { |
|
|
|
Right( |
|
|
|
Workout.parse("") shouldBe a[WorkoutNote] |
|
|
|
WorkoutDef("running", "run-fast", Seq( |
|
|
|
Workout.parse("running") shouldBe a[WorkoutNote] |
|
|
|
|
|
|
|
Workout.parse("running !") shouldBe a[WorkoutNote] |
|
|
|
|
|
|
|
Workout.parse("running run-fast") shouldBe a[WorkoutNote] |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"parse a workout definition correctly" in { |
|
|
|
|
|
|
|
Workout.parse(testWO) shouldBe WorkoutDef("running", "run-fast", Seq( |
|
|
|
WarmupStep(TimeDuration(minutes = 10)), |
|
|
|
WarmupStep(TimeDuration(minutes = 10)), |
|
|
|
RepeatStep(2, Seq( |
|
|
|
RepeatStep(2, Seq( |
|
|
|
IntervalStep(DistanceDuration(1500, m), Some(PaceTarget(Pace(msys.distance, "4:30"), Pace(msys.distance, "5:00")))), |
|
|
|
IntervalStep(DistanceDuration(1500, m), Some(PaceTarget(Pace(msys.distance, "4:30"), Pace(msys.distance, "5:00")))), |
|
|
|
RecoverStep(TimeDuration(1, 30), Some(HrZoneTarget(2))))), |
|
|
|
RecoverStep(TimeDuration(1, 30), Some(HrZoneTarget(2))))), |
|
|
|
CooldownStep(LapButtonPressed))))) |
|
|
|
CooldownStep(LapButtonPressed))) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
"Workout" should "parse various printable workout-names correctly" in { |
|
|
|
"parse various printable workout-names correctly" in { |
|
|
|
|
|
|
|
|
|
|
|
val testNames = Seq("abcz", "123 xyw", """abc!/+-@,?*;:_!\"#$%&/()=?*""") |
|
|
|
val testNames = Seq("abcz", "123 xyw", """abc!/+-@,?*;:_!\"#$%&/()=?*""") |
|
|
|
|
|
|
|
|
|
|
|
testNames.foreach { testName => |
|
|
|
testNames.foreach { testName => |
|
|
|
val x = Workout.parseDef(testWO.replace("run-fast", testName)) |
|
|
|
val x = Workout.parse(testWO.replace("run-fast", testName)) |
|
|
|
x.right.get.name should be(testName) |
|
|
|
x shouldBe a[WorkoutDef] |
|
|
|
} |
|
|
|
x.asInstanceOf[WorkoutDef].name should be(testName) |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
"Workout" should "dump json correctly" in { |
|
|
|
|
|
|
|
val is = getClass.getClassLoader.getResourceAsStream("run-fast.json") |
|
|
|
|
|
|
|
val expectJson = Json.parse(is) |
|
|
|
|
|
|
|
Workout.parseDef(testWO).map(_.json) should be(Right(expectJson)) |
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
"Workout" should "support cycling ws" in { |
|
|
|
"parse cycling workouts" in { |
|
|
|
val testBike = "cycling: cycle-test\r\n- warmup: 5:00\n- bike: 20km @ 20.0-100kph\r- cooldown: lap-button" |
|
|
|
val testBike = "cycling: cycle-test\r\n- warmup: 5:00\n- bike: 20km @ 20.0-100kph\r- cooldown: lap-button" |
|
|
|
Workout.parseDef(testBike) should be( |
|
|
|
Workout.parse(testBike) shouldBe WorkoutDef("cycling", "cycle-test", Seq( |
|
|
|
Right( |
|
|
|
|
|
|
|
WorkoutDef("cycling", "cycle-test", Seq( |
|
|
|
|
|
|
|
WarmupStep(TimeDuration(minutes = 5)), |
|
|
|
WarmupStep(TimeDuration(minutes = 5)), |
|
|
|
IntervalStep(DistanceDuration(20, km), Some(SpeedTarget(Speed(km, "20.0"), Speed(km, "100")))), |
|
|
|
IntervalStep(DistanceDuration(20, km), Some(SpeedTarget(Speed(km, "20.0"), Speed(km, "100")))), |
|
|
|
CooldownStep(LapButtonPressed))))) |
|
|
|
CooldownStep(LapButtonPressed))) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"validate on a workout definition level" in { |
|
|
|
|
|
|
|
Workout.parse("running:") shouldBe a[WorkoutDefFailure] |
|
|
|
|
|
|
|
Workout.parse("running: run-fast\nhm") shouldBe a[WorkoutDefFailure] |
|
|
|
|
|
|
|
Workout.parse("running: run\n- warmup: 10:00") shouldBe a[WorkoutDefFailure] |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"validate on a step level" in { |
|
|
|
|
|
|
|
Workout.parse("running: run\n- run: 5km 2+2") should matchPattern { |
|
|
|
|
|
|
|
case WorkoutStepFailure(_, "Cannot parse step parameters 5km 2+2") => |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
Workout.parse("running: run\n- run: 10:00\n - run: 1500m @ 4:30-5:00") should matchPattern { |
|
|
|
|
|
|
|
case WorkoutStepFailure(_, "'run' cannot contain sub-steps, it must be 'repeat'") => |
|
|
|
} |
|
|
|
} |
|
|
|
|
|
|
|
Workout.parse("running: run\n- and: fail at this step") should matchPattern { |
|
|
|
|
|
|
|
case WorkoutStepFailure(_, "'and' is not a duration step type") => |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
Workout.parse("running: run\n- run: 10km @ 20x") should matchPattern { |
|
|
|
|
|
|
|
case WorkoutStepFailure(_, "'20x' is not a valid target specification") => |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
"Workout should" should { |
|
|
|
|
|
|
|
"dump json correctly" in { |
|
|
|
|
|
|
|
val is = getClass.getClassLoader.getResourceAsStream("run-fast.json") |
|
|
|
|
|
|
|
val expectJson = Json.parse(is) |
|
|
|
|
|
|
|
Workout.parse(testWO).json() should be(expectJson) |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
} |
|
|
|
} |
|
|
|
|