alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

Play Framework/Scala example source code file (BodyParserSpec.scala)

This example Play Framework source code file (BodyParserSpec.scala) is included in my "Source Code Warehouse" project. The intent of this project is to help you more easily find Play Framework (and Scala) source code examples by using tags.

All credit for the original source code belongs to Play Framework; I'm just trying to make examples easier to find. (For my Scala work, see my Scala examples and tutorials.)

Play Framework tags/keywords

a, api, arbitrary, bodyparser, concurrent, done, future, int, left, library, play, play framework, playspecification, result, right, test

The BodyParserSpec.scala Play Framework example source code

/*
 * Copyright (C) 2009-2013 Typesafe Inc. <http://www.typesafe.com>
 */
package play.it.http.parsing

import scala.concurrent.Future

import play.api.libs.iteratee.{Done, Enumerator, ExecutionSpecification, Input}
import play.api.mvc.{BodyParser, BodyParsers, Results, Result}
import play.api.test.{FakeRequest, PlaySpecification}

import org.specs2.ScalaCheck
import org.scalacheck.{Arbitrary, Gen}


object BodyParserSpec extends PlaySpecification with ExecutionSpecification with ScalaCheck {

  def run[A](bodyParser: BodyParser[A]) = {
    import scala.concurrent.ExecutionContext.Implicits.global
    await {
      Future {
        bodyParser(FakeRequest())
      } .flatMap {
        Enumerator.empty |>>> _
      }
    }
  }

  def constant[A](a: A): BodyParser[A] =
    BodyParser("constant") { request =>
      Done(Right(a), Input.Empty)
    }

  def simpleResult(s: Result): BodyParser[Any] =
    BodyParser("simple result") { request =>
      Done(Left(s), Input.Empty)
    }

  implicit val arbResult: Arbitrary[Result] =
    Arbitrary {
      Gen.oneOf(
        Results.Ok,
        Results.BadRequest, Results.NotFound,
        Results.InternalServerError
      )
    }


  /* map and mapM should satisfy the functor laws, namely,
   * preservation of identity and function composition.
   * flatMap and flatMapM should satisfy the monad laws, namely,
   * left and right identity, and associativity.
   * The *M versions are simply lifted to Future.
   * When the given function is right-biased, validate and
   * validateM are equivalent to map and mapM, respectively, so
   * should satisfy the functor laws. When left-biased, the result
   * will override the result of the body parser being validated.
   * All of the functions in question should pass a simple result
   * through.
   */


  "BodyParser.map" should {

    "satisfy functor law 1" in prop { (x: Int) =>
      mustExecute(1) { implicit ec => // one execution from `map`
        run {
          constant(x).map(identity)
        } must beRight(x)
      }
    }

    "satisfy functor law 2" in prop { (x: Int) =>
      val inc = (i: Int) => i + 1
      val dbl = (i: Int) => i * 2
      mustExecute(3) { implicit ec => // three executions from `map`
        run {
          constant(x).map(inc)
                     .map(dbl)
        } must_== run {
          constant(x).map(inc andThen dbl)
        }
      }
    }

    "pass through simple result" in prop { (s: Result) =>
      mustExecute(1) { implicit ec => // one execution from `map`
        run {
          simpleResult(s).map(identity)
        } must beLeft(s)
      }
    }
  }

  "BodyParser.mapM" should {

    "satisfy lifted functor law 1" in prop { (x: Int) =>
      mustExecute(1) { implicit ec => // one execution from `mapM`
        run {
          constant(x).mapM(Future.successful)
        } must beRight(x)
      }
    }

    "satisfy lifted functor law 2" in prop { (x: Int) =>
      val inc = (i: Int) => Future.successful(i + 1)
      val dbl = (i: Int) => Future.successful(i * 2)
      mustExecute(3, 1) { (mapMEC, flatMapEC) =>
        val flatMapPEC = flatMapEC.prepare()
        /* three executions from `BodyParser.mapM`
         * and one from `Future.flatMapM`
         */
        run {
          constant(x).mapM(inc)(mapMEC)
                     .mapM(dbl)(mapMEC)
        } must_== run {
          constant(x).mapM { y =>
            inc(y).flatMap(dbl)(flatMapPEC)
          }(mapMEC)
        }
      }
    }

    "pass through simple result" in prop { (s: Result) =>
      mustExecute(1) { implicit ec => // one execution from `mapM`
        run {
          simpleResult(s).mapM(Future.successful)
        } must beLeft(s)
      }
    }
  }

  "BodyParser.flatMap" should {

    "satisfy monad law 1" in prop { (x: Int) =>
      val inc = (i: Int) => constant(i + 1)
      mustExecute(1) { implicit ec => // one execution from `flatMap`
        run {
          constant(x).flatMap(inc)
        } must_== run {
          inc(x)
        }
      }
    }

    "satisfy monad law 2" in prop { (x: Int) =>
      mustExecute(1) { implicit ec => // one execution from `flatMap`
        run {
          constant(x).flatMap(constant)
        } must_== run {
          constant(x)
        }
      }
    }

    "satisfy monad law 3" in prop { (x: Int) =>
      val inc = (i: Int) => constant(i + 1)
      val dbl = (i: Int) => constant(i * 2)
      mustExecute(3, 1) { (outerEC, innerEC) => // four executions from `flatMap`
        val innerPEC = innerEC.prepare()
        run {
          constant(x).flatMap(inc)(outerEC)
                     .flatMap(dbl)(outerEC)
        } must_== run {
          constant(x).flatMap { y =>
            inc(y).flatMap(dbl)(innerPEC)
          }(outerEC)
        }
      }
    }

    "pass through simple result" in prop { (s: Result) =>
      mustExecute(1) { implicit ec => // one execution from `flatMap`
        run {
          simpleResult(s).flatMap(constant)
        } must beLeft(s)
      }
    }
  }

  "BodyParser.flatMapM" should {

    "satisfy lifted monad law 1" in prop { (x: Int) =>
      val inc = (i: Int) => constant(i + 1)
      mustExecute(2) { implicit ec =>
        /* one invocation of `flatMapM`
         * giving two internal executions
         */
        run {
          constant(x).flatMapM(inc andThen Future.successful)
        } must_== run {
          inc(x)
        }
      }
    }

    "satisfy lifted monad law 2" in prop { (x: Int) =>
      mustExecute(2) { implicit ec => // two executions from `flatMapM`
        run {
          constant(x).flatMapM { y => Future.successful(constant(y)) }
        } must_== run {
          constant(x)
        }
      }
    }

    "satisfy lifted monad law 3" in prop { (x: Int) =>
      val inc = (i: Int) => Future.successful(constant(i + 1))
      val dbl = (i: Int) => Future.successful(constant(i * 2))
      mustExecute(6, 2, 1) { (flatMapMEC, innerFlatMapMEC, innerMapEC) =>
        val innerFlatMapMPEC = innerFlatMapMEC.prepare()
        val innerMapPEC = innerMapEC.prepare()
        /* four invocations of `flatMapM`
         * giving eight internal executions
         * and one from `Future.map`
         */
        run {
          constant(x).flatMapM(inc)(flatMapMEC)
                     .flatMapM(dbl)(flatMapMEC)
        } must_== run {
          constant(x).flatMapM { y =>
            inc(y).map { z =>
              z.flatMapM(dbl)(innerFlatMapMPEC)
            }(innerMapPEC)
          }(flatMapMEC)
        }
      }
    }

    "pass through simple result" in prop { (s: Result) =>
      mustExecute(1) { implicit ec => // one execution from `flatMapM`
        run {
          simpleResult(s).flatMapM { x => Future.successful(constant(x)) }
        } must beLeft(s)
      }
    }
  }

  "BodyParser.validate" should {

    "satisfy right-biased functor law 1" in prop { (x: Int) =>
      val id = (i: Int) => Right(i)
      mustExecute(1) { implicit ec => // one execution from `validate`
        run {
          constant(x).validate(id)
        } must beRight(x)
      }
    }

    "satisfy right-biased functor law 2" in prop { (x: Int) =>
      val inc = (i: Int) => Right(i + 1)
      val dbl = (i: Int) => Right(i * 2)
      mustExecute(3) { implicit ec => // three executions from `validate`
        run {
          constant(x).validate(inc)
                     .validate(dbl)
        } must_== run {
          constant(x).validate { y =>
            inc(y).right.flatMap(dbl)
          }
        }
      }
    }

    "pass through simple result (case 1)" in prop { (s: Result) =>
      mustExecute(1) { implicit ec => // one execution from `validate`
        run {
          simpleResult(s).validate(Right.apply)
        } must beLeft(s)
      }
    }

    "pass through simple result (case 2)" in prop { (s1: Result, s2: Result) =>
      mustExecute(1) { implicit ec => // one execution from `validate`
        run {
          simpleResult(s1).validate { _ => Left(s2) }
        } must beLeft(s1)
      }
    }

    "fail with simple result" in prop { (s: Result) =>
      mustExecute(1) { implicit ec => // one execution from `validate`
        run {
          constant(0).validate { _ => Left(s) }
        } must beLeft(s)
      }
    }
  }

  "BodyParser.validateM" should {

    "satisfy right-biased, lifted functor law 1" in prop { (x: Int) =>
      val id = (i: Int) => Future.successful(Right(i))
      mustExecute(1) { implicit ec => // one execution from `validateM`
        run {
          constant(x).validateM(id)
        } must beRight(x)
      }
    }

    "satisfy right-biased, lifted functor law 2" in prop { (x: Int) =>
      val inc = (i: Int) => Future.successful(Right(i + 1))
      val dbl = (i: Int) => Future.successful(Right(i * 2))
      mustExecute(3) { implicit ec => // three executions from `validateM`
        run {
          constant(x).validateM(inc).validateM(dbl)
        } must_== run {
          constant(x).validateM { y =>
            Future.successful(Right((y + 1) * 2))
          }
        }
      }
    }

    "pass through simple result (case 1)" in prop { (s: Result) =>
      mustExecute(1) { implicit ec => // one execution from `validateM`
        run {
          simpleResult(s).validateM { x => Future.successful(Right(x)) }
        } must beLeft(s)
      }
    }

    "pass through simple result (case 2)" in prop { (s1: Result, s2: Result) =>
      mustExecute(1) { implicit ec => // one execution from `validateM`
        run {
          simpleResult(s1).validateM { _ => Future.successful(Left(s2)) }
        } must beLeft(s1)
      }
    }

    "fail with simple result" in prop { (s: Result) =>
      mustExecute(1) { implicit ec => // one execution from `validateM`
        run {
          constant(0).validateM { _ => Future.successful(Left(s)) }
        } must beLeft(s)
      }
    }
  }

}

Other Play Framework source code examples

Here is a short list of links related to this Play Framework BodyParserSpec.scala source code file:

... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.