Merge pull request #44 from marxav/power_and_cadence

Add power and cadence as possible targets
master
Nikola Petkov 7 years ago committed by GitHub
commit c8485b44a0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 6
      README.md
  2. 24
      src/main/scala/com.github.mgifos.workouts/model/Target.scala
  3. 24
      src/test/scala/com/github/mgifos/workouts/model/TargetSpec.scala

@ -93,7 +93,7 @@ The reserved keywords of the notation are: workout, warmup, cooldown, run, bike,
**`<time-duration>`** := `<minutes>:<seconds>`
**`<target>`** := `<zone-target> | <pace-target> | <hr-target>`
**`<target>`** := `<zone-target> | <pace-target> | <hr-target> | <speed-target> | <power-target> | <cadence-target>`
**`<zone-target>`** := `z[1-6]`
@ -101,6 +101,10 @@ The reserved keywords of the notation are: workout, warmup, cooldown, run, bike,
**`<hr-target>`** := `\d{1,3} - \d{1,3} bpm`
**`<power-target>`** := `\d{1,3} - \d{1,3} W`
**`<cadence-target>`** := `\d{1,3} - \d{1,3} rpm`
**`<speed-target>`** := `<kph-speed> - <kph-speed> (kph | mph)?`
**`<pace>`** := `<minutes>:<seconds>`

@ -36,6 +36,26 @@ case class PaceTarget(from: Pace, to: Pace) extends Target {
)
}
case class PowerCustomTarget(from: Int, to: Int) extends Target {
override def json =
Json.obj(
"targetType" -> Json.obj("workoutTargetTypeId" -> 2, "workoutTargetTypeKey" -> "power.zone"),
"targetValueOne" -> from,
"targetValueTwo" -> to,
"zoneNumber" -> JsNull
)
}
case class CadenceCustomTarget(from: Int, to: Int) extends Target {
override def json =
Json.obj(
"targetType" -> Json.obj("workoutTargetTypeId" -> 3, "workoutTargetTypeKey" -> "cadence.zone"),
"targetValueOne" -> from,
"targetValueTwo" -> to,
"zoneNumber" -> JsNull
)
}
case class SpeedTarget(from: Speed, to: Speed) extends Target {
override def json =
Json.obj(
@ -75,14 +95,18 @@ case class Speed(unit: DistanceUnits.DistanceUnit, exp: String) {
}
object Target {
private val CadenceCustomRx = """^(\d{1,3})\s*-\s*(\d{1,3})\s*rpm$""".r
private val HrZoneRx = """^z(\d)$""".r
private val HrCustomRx = """^(\d{1,3})\s*-\s*(\d{1,3})\s*bpm$""".r
private val PaceRangeRx = """^(\d{1,2}:\d{2})\s*-\s*(\d{1,2}:\d{2})\s*(mpk|mpm)?$""".r
private val PowerCustomRx = """^(\d{1,3})\s*-\s*(\d{1,3})\s*W$""".r
private val SpeedRangeRx = """^(\d{1,3}(\.\d{1})?)\s*-\s*(\d{1,3}(\.\d{1})?)\s*(kph|mph)?""".r
def parse(x: String)(implicit msys: MeasurementSystems.MeasurementSystem): Target = x.trim match {
case CadenceCustomRx(from, to) => CadenceCustomTarget(from.toInt, to.toInt)
case HrZoneRx(zone) => HrZoneTarget(zone.toInt)
case HrCustomRx(from, to) => HrCustomTarget(from.toInt, to.toInt)
case PowerCustomRx(from, to) => PowerCustomTarget(from.toInt, to.toInt)
case SpeedRangeRx(from, _, to, _, uom) =>
val du = Option(uom).fold(msys.distance)(DistanceUnits.withSpeedUOM)
SpeedTarget(Speed(du, from), Speed(du, to))

@ -43,4 +43,28 @@ class TargetSpec extends FlatSpec with Matchers {
"targetValueTwo" -> 150,
"zoneNumber" -> JsNull))
}
"Target" should "handle custom POWER specification correctly" in {
val powTarget = Target.parse("230-250 W").asInstanceOf[PowerCustomTarget]
powTarget should be(PowerCustomTarget(230, 250))
powTarget.json should be(Json.obj(
"targetType" -> Json.obj(
"workoutTargetTypeId" -> 2,
"workoutTargetTypeKey" -> "power.zone"),
"targetValueOne" -> 230,
"targetValueTwo" -> 250,
"zoneNumber" -> JsNull))
}
"Target" should "handle custom CADENCE specification correctly" in {
val cadenceTarget = Target.parse("80-90 rpm").asInstanceOf[CadenceCustomTarget]
cadenceTarget should be(CadenceCustomTarget(80, 90))
cadenceTarget.json should be(Json.obj(
"targetType" -> Json.obj(
"workoutTargetTypeId" -> 3,
"workoutTargetTypeKey" -> "cadence.zone"),
"targetValueOne" -> 80,
"targetValueTwo" -> 90,
"zoneNumber" -> JsNull))
}
}

Loading…
Cancel
Save