Skip to content

Commit

Permalink
first commit
Browse files Browse the repository at this point in the history
  • Loading branch information
aconbere committed Oct 24, 2012
0 parents commit ca7ac5a
Show file tree
Hide file tree
Showing 4 changed files with 107 additions and 0 deletions.
1 change: 1 addition & 0 deletions .gitignore
@@ -0,0 +1 @@
target/
13 changes: 13 additions & 0 deletions build.sbt
@@ -0,0 +1,13 @@
name := "statemachine"

version := "0.0.1"

scalaVersion := "2.9.1"

scalacOptions += "-deprecation"

libraryDependencies += "org.scalatest" %% "scalatest" % "1.8" % "test"

libraryDependencies += "junit" % "junit" % "4.10" % "test"

testOptions in Test += Tests.Argument("-oDF")
18 changes: 18 additions & 0 deletions src/main/scala/StateMachine.scala
@@ -0,0 +1,18 @@
package com.conbere.statemachine

trait Event
trait State

trait StateMachine[Self <: StateMachine[Self]] {
type Transition = PartialFunction[(State, Event), Self]

val transitions: Transition
val state: State

def defaultTransition: Transition

def trigger(event: Event): Self = {
(transitions orElse defaultTransition)((state, event))
}
}

75 changes: 75 additions & 0 deletions src/test/scala/StateMachineSuite.scala
@@ -0,0 +1,75 @@
import scala.io.Source

import org.scalatest.FunSuite
import org.scalatest.junit.JUnitRunner

import org.junit.runner.RunWith

import com.conbere.statemachine._

case object Locked extends State
case object UnLocked extends State

case class Coin(val value: Int) extends Event
case object Push extends Event

class Turnstile(val value: Int, val state: State)
extends StateMachine[Turnstile] {
def this() = this(0, Locked)

val requiredPayment = 10

override def defaultTransition: Transition = {
case _ => this
}

val transitions: Transition = {
case (Locked, Coin(v)) =>
if (value + v >= requiredPayment)
new Turnstile(0, UnLocked)
else
new Turnstile(value + v, state)
case (Locked, Push) =>
this
case (UnLocked, Push) =>
new Turnstile()
case (UnLocked, Coin(_)) =>
this
}

override def toString = "Turnstile: %s: %s".format(state, value)
}

@RunWith(classOf[JUnitRunner])
class StateMachineSuite extends FunSuite {
trait StateMachineM {
val t = new Turnstile()
}

test("turnstile") {
new StateMachineM {
assert(t.state == Locked)
assert(t.value == 0)

val t2 = t.trigger(Push)

assert(t2.state == Locked)
assert(t2.value == 0)

val t3 = t2.trigger(Coin(5))

assert(t3.state == Locked)
assert(t3.value == 5)

val t4 = t3.trigger(Coin(5))

assert(t4.state == UnLocked)
assert(t4.value == 0)

val t5 = t4.trigger(Push)

assert(t5.state == Locked)
assert(t5.value == 0)
}
}
}

0 comments on commit ca7ac5a

Please sign in to comment.