~ huge refactoring on Specs: much easier to understand and to add new specs
authorAlexandre Bertails <bertails@gmail.com>
Mon, 10 Oct 2011 17:47:51 -0400
changeset 48 055d27e60d30
parent 47 5733487193e1
child 50 ae342bca35a3
child 56 1ef59b9dab9b
~ huge refactoring on Specs: much easier to understand and to add new specs
src/main/scala/Main.scala
src/test/scala/AccessContentSpecs.scala
src/test/scala/CreateContentSpecs.scala
src/test/scala/OtherSpecs.scala
src/test/scala/ReadWriteWebSpecs.scala
src/test/scala/SparqlQuerySpecs.scala
src/test/scala/SparqlUpdateSpecs.scala
src/test/scala/Test.scala
src/test/scala/util/specs.scala
src/test/scala/util/utiltest.scala
src/test/scala/utiltest.scala
--- a/src/main/scala/Main.scala	Sat Oct 08 16:45:44 2011 -0400
+++ b/src/main/scala/Main.scala	Mon Oct 10 17:47:51 2011 -0400
@@ -24,7 +24,7 @@
 
 import org.w3.readwriteweb.util._
 
-class ReadWriteWeb(rm:ResourceManager) {
+class ReadWriteWeb(rm: ResourceManager) {
   
   val logger:Logger = LoggerFactory.getLogger(this.getClass)
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/test/scala/AccessContentSpecs.scala	Mon Oct 10 17:47:51 2011 -0400
@@ -0,0 +1,46 @@
+package org.w3.readwriteweb
+
+import org.w3.readwriteweb.util._
+import org.w3.readwriteweb.utiltest._
+
+import dispatch._
+
+object GetStrictModeSpec extends FilesystemBased with SomeRDF with SomeURI {
+  
+  "a GET on a URL that does not exist" should {
+    "return a 404" in {
+      val httpCode:Int = Http.when( _ => true)(uri get_statusCode)
+      httpCode must_== 404
+    }
+  }
+
+}
+
+object GetWikiModeSpec extends FilesystemBased with SomeRDF with SomeURI {
+  
+  override lazy val mode = AllResourcesAlreadyExist
+  
+  "a GET on a URL that does not exist" should {
+    "return a 200 and an empty model" in {
+      val (statusCode, model) = Http(uri >+ {
+        req => (req.get_statusCode,
+                req as_model(uriBase))
+      } )
+      statusCode must_== 200
+      model must beIsomorphicWith (emptyModel)
+    }
+  }
+  
+}
+
+object ContentNegociationSpec extends SomeDataInStore {
+
+  "a GET on Joe's URI" should {
+    "deliver TURTLE and RDF/XML graphs that are isomorphic to each other" in {
+      val rdfxml = Http(uri as_model(uriBase))
+      val turtle = Http(uri <:< Map("Accept" -> "text/turtle") as_model(uriBase, lang="TURTLE"))
+      rdfxml must beIsomorphicWith(turtle)
+    }
+  }
+  
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/test/scala/CreateContentSpecs.scala	Mon Oct 10 17:47:51 2011 -0400
@@ -0,0 +1,96 @@
+package org.w3.readwriteweb
+
+import org.w3.readwriteweb.util._
+import org.w3.readwriteweb.utiltest._
+
+import dispatch._
+
+object PutRDFXMLSpec extends FilesystemBased with SomeRDF with SomeURI {
+
+  "PUTing an RDF document on Joe's URI (which does not exist yet)" should {
+    "return a 201" in {
+      val httpCode = Http(uri.put(rdfxml) get_statusCode)
+      httpCode must_== 201
+    }
+    "create a document on disk" in {
+      resourceOnDisk must exist
+    }
+  }
+  
+  "Joe's URI" should {
+    "now exist and be isomorphic with the original document" in {
+      val (statusCode, via, model) = Http(uri >++ { req => (req.get_statusCode,
+                                                            req.get_header("MS-Author-Via"),
+                                                            req as_model(uriBase))
+                                                  } )
+      statusCode must_== 200
+      via must_== "SPARQL"
+      model must beIsomorphicWith (referenceModel)
+    }
+  }
+  
+}
+
+
+object PostRDFSpec extends SomeDataInStore {
+  
+    val diffRDF =
+"""
+<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> 
+  <foaf:Person rdf:about="#JL" xmlns:foaf="http://xmlns.com/foaf/0.1/">
+    <foaf:openid rdf:resource="/2007/wiki/people/JoeLambda" />
+    <foaf:img rdf:resource="/2007/wiki/people/JoeLambda/images/me.jpg" />
+  </foaf:Person>
+</rdf:RDF>
+"""
+
+  val finalRDF =
+"""
+<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> 
+  <foaf:Person rdf:about="#JL" xmlns:foaf="http://xmlns.com/foaf/0.1/">
+    <foaf:name>Joe Lambda</foaf:name>
+    <foaf:homepage rdf:resource="/2007/wiki/people/JoeLambda" />
+    <foaf:openid rdf:resource="/2007/wiki/people/JoeLambda" />
+    <foaf:img rdf:resource="/2007/wiki/people/JoeLambda/images/me.jpg" />
+  </foaf:Person>
+</rdf:RDF>
+"""  
+    
+  val expectedFinalModel = modelFromString(finalRDF, uriBase).toOption.get
+
+  "POSTing an RDF document to Joe's URI" should {
+    "succeed" in {
+      val httpCode:Int = Http(uri.post(diffRDF) get_statusCode)
+      httpCode must_== 200
+    }
+    "append the diff graph to the initial graph" in {
+      val model = Http(uri as_model(uriBase))
+      model must beIsomorphicWith (expectedFinalModel)
+    }
+  }
+  
+}
+
+
+object PutInvalidRDFXMLSpec extends SomeDataInStore {
+
+  """PUTting not-valid RDF to Joe's URI""" should {
+    "return a 400 Bad Request" in {
+      val statusCode = Http.when(_ == 400)(uri.put("that's bouleshit") get_statusCode)
+      statusCode must_== 400
+    }
+  }
+  
+}
+
+object PostOnNonExistingResourceSpec extends FilesystemBased {
+
+  "POSTing an RDF document to a resource that does not exist" should {
+    val doesnotexist = host / "2007/wiki/doesnotexist"
+    "return a 404" in {
+      val httpCode:Int = Http.when( _ => true)(doesnotexist get_statusCode)
+      httpCode must_== 404
+    }
+  }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/test/scala/OtherSpecs.scala	Mon Oct 10 17:47:51 2011 -0400
@@ -0,0 +1,29 @@
+package org.w3.readwriteweb
+
+import org.w3.readwriteweb.util._
+import org.w3.readwriteweb.utiltest._
+
+import dispatch._
+
+object PostBouleshitSpec extends SomeDataInStore {
+
+  """POSTing something that does not make sense to Joe's URI""" should {
+    "return a 400 Bad Request" in {
+      val statusCode = Http.when(_ == 400)(uri.post("that's bouleshit") get_statusCode)
+      statusCode must_== 400
+    }
+  }
+  
+}
+
+
+object DeleteResourceSpec extends SomeDataInStore {
+
+  """a DELETE request""" should {
+    "not be supported yet" in {
+      val statusCode = Http.when(_ == 405)(uri.copy(method="DELETE") get_statusCode)
+      statusCode must_== 405
+    }
+  }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/test/scala/ReadWriteWebSpecs.scala	Mon Oct 10 17:47:51 2011 -0400
@@ -0,0 +1,23 @@
+package org.w3.readwriteweb
+
+import org.specs._
+
+object ReadWriteWebSpec extends Specification {
+  "The Read Write Web".isSpecifiedBy(
+      // access content
+      GetStrictModeSpec, GetWikiModeSpec,
+      ContentNegociationSpec,
+      // create content
+      PutRDFXMLSpec, PostRDFSpec,
+      PutInvalidRDFXMLSpec, PostOnNonExistingResourceSpec,
+      // sparql query
+      PostSelectSpec, PostConstructSpec, PostAskSpec, 
+      // sparql update
+      PostInsertSpec,
+      // delete content
+      DeleteResourceSpec,
+      // common errors
+      PostBouleshitSpec
+  )
+
+}
\ No newline at end of file
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/test/scala/SparqlQuerySpecs.scala	Mon Oct 10 17:47:51 2011 -0400
@@ -0,0 +1,65 @@
+package org.w3.readwriteweb
+
+import org.w3.readwriteweb.util._
+import org.w3.readwriteweb.utiltest._
+
+import dispatch._
+
+import com.hp.hpl.jena.rdf.model._
+import com.hp.hpl.jena.query._
+
+import com.codecommit.antixml._
+
+object PostSelectSpec extends SomeDataInStore {
+
+  val selectFoafName =
+"""
+PREFIX foaf: <http://xmlns.com/foaf/0.1/>
+SELECT ?name WHERE { [] foaf:name ?name }
+"""
+  
+  """POSTing "SELECT ?name WHERE { [] foaf:name ?name }" to Joe's URI""" should {
+    "return Joe's name" in {
+      val resultSet = Http(uri.post(selectFoafName) >- { body => ResultSetFactory.fromXML(body) } )
+      resultSet.next().getLiteral("name").getString must_== "Joe Lambda"
+    }
+  }
+  
+}
+
+
+object PostAskSpec extends SomeDataInStore {
+
+  val askFoafName =
+"""
+PREFIX foaf: <http://xmlns.com/foaf/0.1/>
+ASK { [] foaf:name ?name }
+"""
+  
+  """POSTing "ASK ?name WHERE { [] foaf:name ?name }" to Joe's URI""" should {
+    "return true" in {
+      val result: Boolean =
+        Http(uri.post(askFoafName) >~ { s => 
+          (XML.fromSource(s) \ "boolean" \ text).head.toBoolean
+          } )
+      result must_== true
+    }
+  }
+  
+}
+
+object PostConstructSpec extends SomeDataInStore {
+
+  val constructIdentity =
+"""
+CONSTRUCT { ?s ?p ?o } WHERE { ?s ?p ?o }
+"""
+  
+  """POSTing "CONSTRUCT { ?s ?p ?o } WHERE { ?s ?p ?o }" to Joe's URI""" should {
+    "return an isomorphic RDF graph" in {
+      val model = Http(uri as_model(uriBase))
+      model must beIsomorphicWith (referenceModel)
+    }
+  }
+
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/test/scala/SparqlUpdateSpecs.scala	Mon Oct 10 17:47:51 2011 -0400
@@ -0,0 +1,27 @@
+package org.w3.readwriteweb
+
+import org.w3.readwriteweb.util._
+import org.w3.readwriteweb.utiltest._
+
+import dispatch._
+
+object PostInsertSpec extends SomeDataInStore {
+
+  val insertQuery =
+"""
+PREFIX foaf: <http://xmlns.com/foaf/0.1/>
+INSERT DATA { </2007/wiki/people/JoeLambda#JL> foaf:openid </2007/wiki/people/JoeLambda> }
+"""
+  
+  "POSTing an INSERT query on Joe's URI (which does not exist yet)" should {
+    "succeed" in {
+      val httpCode = Http(uri.post(insertQuery) get_statusCode)
+      httpCode must_== 200
+    }
+    "produce a graph with one more triple than the original one" in {
+      val model = Http(uri as_model(uriBase))
+      model.size must_== (referenceModel.size + 1)
+    }
+  }
+  
+}
--- a/src/test/scala/Test.scala	Sat Oct 08 16:45:44 2011 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,212 +0,0 @@
-package org.w3.readwriteweb
-
-import org.specs._
-import java.net.URL
-import unfiltered.response._
-import unfiltered.request._
-import dispatch._
-import java.io._
-
-import com.codecommit.antixml._
-import grizzled.file.GrizzledFile._
-
-import com.hp.hpl.jena.rdf.model._
-import com.hp.hpl.jena.query._
-import com.hp.hpl.jena.update._
-
-import org.w3.readwriteweb.util._
-import org.w3.readwriteweb.utiltest._
-
-object ReadWriteWebSpec extends Specification with unfiltered.spec.jetty.Served {
-
-  val base = new File(new File(System.getProperty("java.io.tmpdir")), "readwriteweb")
-  val joe = host / "2007/wiki/people/JoeLambda"
-  val joeBaseURI = baseURI(joe)
-  val joeOnDisk = new File(base, "people/JoeLambda")
-  
-  //base.deleteRecursively()
-
-  doBeforeSpec {
-    if (base.exists)
-      base.deleteRecursively()
-    base.mkdir()
-  }
-  
-  doAfterSpec {
-//    if (joeOnDisk.exists) joeOnDisk.delete()
-  }
-  
-  val filesystem = new Filesystem(base, "/2007/wiki", "N3")(ResourcesDontExistByDefault)
-
-  def setup = { _.filter(new ReadWriteWeb(filesystem).read) }
-    
-  val joeRDF =
-"""
-<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> 
-  <foaf:Person rdf:about="#JL" xmlns:foaf="http://xmlns.com/foaf/0.1/">
-    <foaf:name>Joe Lambda</foaf:name>
-    <foaf:homepage rdf:resource="/2007/wiki/people/JoeLambda" />
-  </foaf:Person>
-</rdf:RDF>
-"""
-  
-  val initialModel = modelFromString(joeRDF, joeBaseURI).toOption.get
-
-  "a GET on a URL that does not exist" should {
-    "return a 404" in {
-      val httpCode:Int = Http.when( _ => true)(joe get_statusCode)
-      httpCode must_== 404
-    }
-  }
-  
-  "PUTing an RDF document on Joe's URI (which does not exist yet)" should {
-    "return a 201" in {
-      val httpCode:Int = Http(joe.put(joeRDF) get_statusCode)
-      httpCode must_== 201
-    }
-    "create a document on disk" in {
-      joeOnDisk must exist
-    }
-  }
-  
-  "Joe's URI" should {
-    "now exist and be isomorphic with the original document" in {
-      val (statusCode, via, model) = Http(joe >++ { req => (req.get_statusCode,
-                                                            req.get_header("MS-Author-Via"),
-                                                            req as_model(joeBaseURI))
-                                                  } )
-      statusCode must_== 200
-      via must_== "SPARQL"
-      model must beIsomorphicWith (initialModel)
-    }
-  }
-  
-  val insertQuery =
-"""
-PREFIX foaf: <http://xmlns.com/foaf/0.1/>
-INSERT DATA { </2007/wiki/people/JoeLambda#JL> foaf:openid </2007/wiki/people/JoeLambda> }
-"""
-  
-  "POSTing an INSERT query on Joe's URI (which does not exist yet)" should {
-    "succeed" in {
-      val httpCode:Int = Http(joe.post(insertQuery) get_statusCode)
-      httpCode must_== 200
-    }
-    "produce a graph with one more triple than the original one" in {
-      val model = Http(joe as_model(joeBaseURI))
-      model.size must_== (initialModel.size + 1)
-    }
-  }
-
-  "a GET on Joe's URI" should {
-    "deliver TURTLE and RDF/XML graphs that are isomorphic to each other" in {
-      val rdfxml = Http(joe as_model(joeBaseURI))
-      val turtle = Http(joe <:< Map("Accept" -> "text/turtle") as_model(joeBaseURI, lang="TURTLE"))
-      rdfxml must beIsomorphicWith(turtle)
-    }
-  }
-  
-  val diffRDF =
-"""
-<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> 
-  <foaf:Person rdf:about="#JL" xmlns:foaf="http://xmlns.com/foaf/0.1/">
-    <foaf:img rdf:resource="/2007/wiki/people/JoeLambda/images/me.jpg" />
-  </foaf:Person>
-</rdf:RDF>
-"""
-
-  val finalRDF =
-"""
-<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> 
-  <foaf:Person rdf:about="#JL" xmlns:foaf="http://xmlns.com/foaf/0.1/">
-    <foaf:name>Joe Lambda</foaf:name>
-    <foaf:homepage rdf:resource="/2007/wiki/people/JoeLambda" />
-    <foaf:openid rdf:resource="/2007/wiki/people/JoeLambda" />
-    <foaf:img rdf:resource="/2007/wiki/people/JoeLambda/images/me.jpg" />
-  </foaf:Person>
-</rdf:RDF>
-"""  
-    
-  val expectedFinalModel = modelFromString(finalRDF, joeBaseURI).toOption.get
-
-  "POSTing an RDF document to Joe's URI" should {
-    "succeed" in {
-      val httpCode:Int = Http(joe.post(diffRDF) get_statusCode)
-      httpCode must_== 200
-    }
-    "append the diff graph to the initial graph" in {
-      val model = Http(joe as_model(joeBaseURI))
-      model must beIsomorphicWith (expectedFinalModel)
-    }
-  }
-
-  "POSTing an RDF document to a resource that does not exist" should {
-    val doesnotexist = host / "2007/wiki/doesnotexist"
-    "return a 404" in {
-      val httpCode:Int = Http.when( _ => true)(doesnotexist get_statusCode)
-      httpCode must_== 404
-    }
-  }
-  
-  val selectFoafName =
-"""
-PREFIX foaf: <http://xmlns.com/foaf/0.1/>
-SELECT ?name WHERE { [] foaf:name ?name }
-"""
-  
-  """POSTing "SELECT ?name WHERE { [] foaf:name ?name }" to Joe's URI""" should {
-    "return Joe's name" in {
-      val resultSet = Http(joe.post(selectFoafName) >- { body => ResultSetFactory.fromXML(body) } )
-      resultSet.next().getLiteral("name").getString must_== "Joe Lambda"
-    }
-  }
-  
-  val askFoafName =
-"""
-PREFIX foaf: <http://xmlns.com/foaf/0.1/>
-ASK { [] foaf:name ?name }
-"""
-  
-  """POSTing "ASK ?name WHERE { [] foaf:name ?name }" to Joe's URI""" should {
-    "return true" in {
-      val result:Boolean =
-        Http(joe.post(askFoafName) >~ { s => 
-          (XML.fromSource(s) \ "boolean" \ text).head.toBoolean
-          } )
-      result must_== true
-    }
-  }
-  
-  val constructIdentity =
-"""
-CONSTRUCT { ?s ?p ?o } WHERE { ?s ?p ?o }
-"""
-  
-  """POSTing "CONSTRUCT { ?s ?p ?o } WHERE { ?s ?p ?o }" to Joe's URI""" should {
-    "return an isomorphic RDF graph" in {
-      val model = Http(joe as_model(joeBaseURI))
-      model must beIsomorphicWith (expectedFinalModel)
-    }
-  }
-  
-  """POSTing something that does not make sense to Joe's URI""" should {
-    "return a 400 Bad Request" in {
-      val statusCode = Http.when(_ == 400)(joe.post("that's bouleshit") get_statusCode)
-      statusCode must_== 400
-    }
-  }
-  
-  """PUTting not-valid RDF to Joe's URI""" should {
-    "return a 400 Bad Request" in {
-      val statusCode = Http.when(_ == 400)(joe.put("that's bouleshit") get_statusCode)
-      statusCode must_== 400
-    }
-  }
-
-  """a DELETE request""" should {
-    "not be supported yet" in {
-      val statusCode = Http.when(_ == 405)(joe.copy(method="DELETE") get_statusCode)
-      statusCode must_== 405
-    }
-  }
-}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/test/scala/util/specs.scala	Mon Oct 10 17:47:51 2011 -0400
@@ -0,0 +1,88 @@
+package org.w3.readwriteweb.util
+
+import org.w3.readwriteweb._
+
+import org.specs._
+import java.net.URL
+import unfiltered.response._
+import unfiltered.request._
+import dispatch._
+import java.io._
+
+import com.codecommit.antixml._
+import grizzled.file.GrizzledFile._
+
+import com.hp.hpl.jena.rdf.model._
+import com.hp.hpl.jena.query._
+import com.hp.hpl.jena.update._
+
+import org.w3.readwriteweb.util._
+import org.w3.readwriteweb.utiltest._
+
+trait ResourceManaged extends Specification with unfiltered.spec.jetty.Served {
+  
+  def resourceManager: ResourceManager
+  
+  def setup = { _.filter(new ReadWriteWeb(resourceManager).read) }
+ 
+}
+
+trait FilesystemBased extends ResourceManaged {
+  
+  lazy val mode: RWWMode = ResourcesDontExistByDefault
+  
+  lazy val language = "RDF/XML-ABBREV"
+    
+  lazy val baseURL = "/2007/wiki"
+  
+  lazy val root = new File(new File(System.getProperty("java.io.tmpdir")), "readwriteweb")
+
+  lazy val resourceManager = new Filesystem(root, baseURL, language)(mode)
+  
+  doBeforeSpec {
+    if (root.exists) root.deleteRecursively()
+    root.mkdir()
+  }
+  
+}
+
+trait SomeRDF extends SomeURI {
+  
+  val rdfxml =
+"""
+<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"> 
+  <foaf:Person rdf:about="#JL" xmlns:foaf="http://xmlns.com/foaf/0.1/">
+    <foaf:name>Joe Lambda</foaf:name>
+    <foaf:homepage rdf:resource="/2007/wiki/people/JoeLambda" />
+  </foaf:Person>
+</rdf:RDF>
+"""
+      
+  val turtle =
+"""
+"""
+    
+  val referenceModel = modelFromString(rdfxml, uriBase).toOption.get
+
+}
+
+trait SomeURI extends FilesystemBased {
+  
+  val emptyModel = com.hp.hpl.jena.rdf.model.ModelFactory.createDefaultModel()
+  
+  lazy val uri = host / "2007/wiki/people/JoeLambda"
+  
+  lazy val uriBase = baseURI(uri)
+  
+  lazy val resourceOnDisk = new File(root, "people/JoeLambda")
+  
+}
+
+trait SomeDataInStore extends FilesystemBased with SomeRDF with SomeURI {
+  
+  doBeforeSpec {
+    val httpCode = Http(uri.put(rdfxml) get_statusCode)
+    httpCode must_== 201
+  }
+  
+}
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/test/scala/util/utiltest.scala	Mon Oct 10 17:47:51 2011 -0400
@@ -0,0 +1,78 @@
+package org.w3.readwriteweb
+
+import javax.servlet._
+import javax.servlet.http._
+import unfiltered.request._
+import unfiltered.response._
+import unfiltered.jetty._
+
+import java.io._
+import scala.io.Source
+
+import org.slf4j.{Logger, LoggerFactory}
+
+import com.hp.hpl.jena.rdf.model._
+import com.hp.hpl.jena.query._
+import com.hp.hpl.jena.update._
+
+import unfiltered.request._
+import unfiltered.response._
+import unfiltered.jetty._
+
+import dispatch._
+
+import org.specs.matcher.Matcher
+
+import org.w3.readwriteweb.util._
+
+package object utiltest {
+  
+  def baseURI(req:Request):String = "%s%s" format (req.host, req.path)
+  
+  def beIsomorphicWith(that:Model):Matcher[Model] =
+    new Matcher[Model] {
+      def apply(otherModel: => Model) =
+        (that isIsomorphicWith otherModel,
+         "Model A is isomorphic to model B",
+         "%s not isomorphic with %s" format (otherModel.toString, that.toString))
+  }
+  
+  class RequestW(req:Request) {
+
+    def as_model(base:String, lang:String = "RDF/XML-ABBREV"):Handler[Model] =
+      req >> { is => modelFromInputStream(is, base, lang).toOption.get }
+
+    def post(body:String):Request =
+      (req <<< body).copy(method="POST")
+      
+    def put(body:String):Request = req <<< body
+      
+    def get_statusCode:Handler[Int] = new Handler(req, (c, r, e) => c, { case t => () })
+    
+    def get_header(header:String):Handler[String] = req >:> { _(header).head }
+    
+    def get:Request = req.copy(method="GET")
+    
+    def >++ [A, B, C] (block: Request => (Handler[A], Handler[B], Handler[C])) = {
+      Handler(req, { (code, res, opt_ent) =>
+        val (a, b, c) = block( /\ )
+          (a.block(code, res, opt_ent), b.block(code,res,opt_ent), c.block(code,res,opt_ent))
+      } )
+    }
+    
+    def >+ [A, B] (block: Request => (Handler[A], Handler[B])) = {
+      Handler(req, { (code, res, opt_ent) =>
+        val (a, b) = block( /\ )
+        (a.block(code, res, opt_ent), b.block(code,res,opt_ent))
+      } )
+    }
+    
+  }
+  
+  implicit def wrapRequest(req:Request):RequestW = new RequestW(req)
+  
+
+
+
+
+}
\ No newline at end of file
--- a/src/test/scala/utiltest.scala	Sat Oct 08 16:45:44 2011 -0400
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,70 +0,0 @@
-package org.w3.readwriteweb
-
-import javax.servlet._
-import javax.servlet.http._
-import unfiltered.request._
-import unfiltered.response._
-import unfiltered.jetty._
-
-import java.io._
-import scala.io.Source
-
-import org.slf4j.{Logger, LoggerFactory}
-
-import com.hp.hpl.jena.rdf.model._
-import com.hp.hpl.jena.query._
-import com.hp.hpl.jena.update._
-
-import unfiltered.request._
-import unfiltered.response._
-import unfiltered.jetty._
-
-import dispatch._
-
-import org.specs.matcher.Matcher
-
-import org.w3.readwriteweb.util._
-
-package object utiltest {
-  
-  def baseURI(req:Request):String = "%s%s" format (req.host, req.path)
-  
-  def beIsomorphicWith(that:Model):Matcher[Model] =
-    new Matcher[Model] {
-      def apply(otherModel: => Model) =
-        (that isIsomorphicWith otherModel,
-         "Model A is isomorphic to model B",
-         "%s not isomorphic with %s" format (otherModel.toString, that.toString))
-  }
-  
-  class RequestW(req:Request) {
-
-    def as_model(base:String, lang:String = "RDF/XML-ABBREV"):Handler[Model] =
-      req >> { is => modelFromInputStream(is, base, lang).toOption.get }
-
-    def post(body:String):Request =
-      (req <<< body).copy(method="POST")
-      
-    def put(body:String):Request = req <<< body
-      
-    def get_statusCode:Handler[Int] = new Handler(req, (c, r, e) => c, { case t => () })
-    
-    def get_header(header:String):Handler[String] = req >:> { _(header).head }
-    
-    def get:Request = req.copy(method="GET")
-    
-    def >++ [A, B, C] (block: Request => (Handler[A], Handler[B], Handler[C])) = {
-      Handler(req, { (code, res, opt_ent) =>
-        val (a, b, c) = block( /\ )
-          (a.block(code, res, opt_ent), b.block(code,res,opt_ent), c.block(code,res,opt_ent))
-      } )
-    }
-  }
-  
-  implicit def wrapRequest(req:Request):RequestW = new RequestW(req)
-  
-
-
-
-
-}
\ No newline at end of file