Created
February 26, 2018 14:19
-
-
Save yannick-cw/959e93117e1c7c8f1733bca2d96ae94c to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.holidaycheck.userflow | |
import scala.util.Try | |
object UrlKata { | |
case class Protocol(value: String) extends AnyVal | |
case class Domain(value: String) extends AnyVal | |
case class Params(params: List[(String, String)]) extends AnyVal | |
case class Path(value: String) extends AnyVal | |
case class Url(protocol: Protocol, domain: Domain, params: Params, path: Option[Path] = None) | |
def parse(str: String): Either[String, Url] = str match { | |
case proto :|| domain / path ? params => Right(Url(proto, domain, params, path)) | |
case _ => Left(s"Failed parsing $str") | |
} | |
object :|| { | |
val ProtocolR = """(https?)://(.+)""".r | |
def unapply(url: String): Option[(Protocol, String)] = url match { | |
case ProtocolR(prot, rest) => Some((Protocol(prot), rest)) | |
case _ => None | |
} | |
} | |
object / { | |
val DomainR = """www\.(.+\..+)/(.*)""".r | |
def unapply(url: String): Option[(Domain, String)] = url match { | |
case DomainR(domain, rest) => Some((Domain(domain), rest)) | |
case _ => None | |
} | |
} | |
object ? { | |
val PathR = """([^\?]*)\??(.*)""".r | |
private def pathParams(params: String) = | |
Params( | |
params | |
.drop(1) | |
.split("&") | |
.flatMap { keyValue => | |
Try { | |
val Array(key, value) = keyValue.split("=") | |
(key, value) | |
}.toOption | |
} | |
.toList) | |
def unapply(path: String): Option[(Option[Path], Params)] = path match { | |
case PathR(p, params) if p.nonEmpty => Some((Some(Path(p)), pathParams(params))) | |
case PathR(_, params) => Some((None, pathParams(params))) | |
} | |
} | |
} | |
package com.holidaycheck.userflow | |
import com.holidaycheck.userflow.UrlKata._ | |
import org.scalatest.{FlatSpec, Matchers} | |
class UrlKataSpec extends FlatSpec with Matchers { | |
val emptyParams = Params(List.empty) | |
it should "parse an url" in { | |
UrlKata.parse("http://www.holidaycheck.com/") shouldBe Right( | |
Url(Protocol("http"), Domain("holidaycheck.com"), emptyParams)) | |
} | |
it should "parse an https protocol url" in { | |
UrlKata.parse("https://www.holidaycheck.com/") shouldBe Right( | |
Url(Protocol("https"), Domain("holidaycheck.com"), emptyParams)) | |
} | |
it should "also parse query parameter and path" in { | |
UrlKata.parse("https://www.holidaycheck.com/passion?search=xx&test=ab") shouldBe Right( | |
Url(Protocol("https"), | |
Domain("holidaycheck.com"), | |
Params(List(("search", "xx"), ("test", "ab"))), | |
Some(Path("passion")))) | |
} | |
// it should "work with more complicated urls" in { | |
// UrlKata.parse("https://images.cdn.holidaycheck.com/passions?q=yoga&hotel=fun%20stuff#a=1&b=2") shouldBe Right( | |
// Url(Protocol("https"), Domain("images.cdn.holidaycheck.com"), Params(List(("search", "xx"), ("test", "ab"))))) | |
// ) | |
// } | |
it should "filter out broken parameter" in { | |
UrlKata.parse("https://www.holidaycheck.com/?watdasIs") shouldBe Right( | |
Url(Protocol("https"), Domain("holidaycheck.com"), emptyParams)) | |
} | |
it should "fail parsing an invalid url" in { | |
UrlKata.parse("http//www.holidaycheck.com/").isLeft shouldBe true | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment