Skip to content

Commit

Permalink
Close #446 - [extras-string] Add case conversion - string.toKebabCase
Browse files Browse the repository at this point in the history
  • Loading branch information
kevin-lee committed Oct 29, 2023
1 parent 8ffdb84 commit 6575d8e
Show file tree
Hide file tree
Showing 2 changed files with 283 additions and 0 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,11 @@ object cases extends cases {
.map(_.toLowerCase(Locale.ENGLISH))
.mkString("_")

def toKebabCase: String =
s.split("[\\s_-]+")
.flatMap(_.splitByCase)
.mkString("-")

@SuppressWarnings(Array("org.wartremover.warts.Equals"))
def splitByCase: Vector[String] = {
@scala.annotation.tailrec
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,278 @@
package extras.strings.syntax.casesSpec.stringCaseOpsSpec

import extras.strings.syntax.casesSpec.Gens
import hedgehog._
import hedgehog.runner._

/** @author Kevin Lee
* @since 2023-10-29
*/
object ToKebabCaseSpec extends Properties {
// String.toKebabCase

import extras.strings.syntax.cases._

def tests: List[Test] = List(
property(
"test String.toKebabCase with already kebab-case",
testToKebabCaseWithAlreadyKebabCase,
),
property("test String.toKebabCase with PascalCases", testToKebabCaseWithPascalCases),
property("test String.toKebabCase with camelCases", testToKebabCaseWithCamelCases),
property("test String.toKebabCase with all UPPERCASE", testToKebabCaseWithUpperCase),
property("test String.toKebabCase with all lowercase", testToKebabCaseWithLowerCase),
property("test String.toKebabCase with all Snake_Cases", testToKebabCaseWithSnakeCases),
property("test String.toKebabCase with all lower_snake_cases", testToKebabCaseWithLowerSnakeCases),
property("test String.toKebabCase with all UPPER_SNAKE_CASES", testToKebabCaseWithUpperSnakeCases),
property("test String.toKebabCase with all Kebab-Cases", testToKebabCaseWithKebabCases),
property("test String.toKebabCase with all lower-kebab-cases", testToKebabCaseWithLowerKebabCases),
property("test String.toKebabCase with all UPPER-KEBAB-CASES", testToKebabCaseWithUpperKebabCases),
property(
"test String.toKebabCase with all space separated String values",
testToKebabCaseWithSpaceSeparatedStringValues,
),
property(
"test String.toKebabCase with all lower space separated String values",
testToKebabCaseWithLowerSpaceSeparatedStringValues,
),
property(
"test String.toKebabCase with all UPPER SPACE SEPARATED STRING VALUES",
testToKebabCaseWithUpperSpaceSeparatedStringValues,
),
)

def testToKebabCaseWithAlreadyKebabCase: Property = for {
expected <- Gen
.string(Gen.lower, Range.linear(1, 10))
.list(Range.linear(1, 10))
.map(_.mkString("-"))
.log("expected")
input <- Gen.constant(expected).log("input")
} yield {
val actual = input.toKebabCase
actual ==== expected
}

def testToKebabCaseWithPascalCases: Property = for {
ss <- Gens.genPascalCase(2, 10).list(Range.linear(1, 4)).log("ss")
input <- Gen.constant(ss.mkString).log("input")
} yield {
val expected = ss.mkString("-")
val actual = input.toKebabCase

val info =
s"""
|> input: $input
|> actual: $actual
|> expected: $expected
|""".stripMargin

(actual ==== expected).log(info)
}

def testToKebabCaseWithCamelCases: Property = for {
s <- Gen.string(Gen.lower, Range.linear(1, 10)).log("s")
ss <- Gens.genPascalCase(2, 10).list(Range.linear(1, 4)).log("ss")
input <- Gen.constant(s + ss.mkString).log("input")
} yield {
val expected = (s :: ss).mkString("-")
val actual = input.toKebabCase

val info =
s"""
|> input: $input
|> actual: $actual
|> expected: $expected
|""".stripMargin

(actual ==== expected).log(info)
}

def testToKebabCaseWithUpperCase: Property = for {
expected <- Gen.string(Gen.upper, Range.linear(1, 10)).log("expected")
input <- Gen.constant(expected).log("input")
} yield {
val actual = input.toKebabCase

val info =
s"""
|> input: $input
|> actual: $actual
|> expected: $expected
|""".stripMargin

(actual ==== expected).log(info)
}

def testToKebabCaseWithLowerCase: Property = for {
expected <- Gen.string(Gen.lower, Range.linear(1, 10)).log("expected")
input <- Gen.constant(expected).log("input")
} yield {
val actual = input.toKebabCase

val info =
s"""
|> input: $input
|> actual: $actual
|> expected: $expected
|""".stripMargin

(actual ==== expected).log(info)
}

def testToKebabCaseWithSnakeCases: Property = for {
ss <- Gens.genPascalCase(1, 10).list(Range.linear(1, 5)).log("ss")
input <- Gen.constant(ss.mkString("_")).log("input")
} yield {
val expected = ss.mkString("-")
val actual = input.toKebabCase

val info =
s"""
|> input: $input
|> actual: $actual
|> expected: $expected
|""".stripMargin

(actual ==== expected).log(info)
}

def testToKebabCaseWithLowerSnakeCases: Property = for {
ss <- Gen.string(Gen.lower, Range.linear(1, 10)).list(Range.linear(1, 5)).log("ss")
input <- Gen.constant(ss.mkString("_")).log("input")
} yield {
val expected = ss.mkString("-")
val actual = input.toKebabCase

val info =
s"""
|> input: $input
|> actual: $actual
|> expected: $expected
|""".stripMargin

(actual ==== expected).log(info)
}

def testToKebabCaseWithUpperSnakeCases: Property = for {
ss <- Gen.string(Gen.upper, Range.linear(1, 10)).list(Range.linear(1, 5)).log("ss")
input <- Gen.constant(ss.mkString("_")).log("input")
} yield {
val expected = ss.mkString("-")
val actual = input.toKebabCase

val info =
s"""
|> input: $input
|> actual: $actual
|> expected: $expected
|""".stripMargin

(actual ==== expected).log(info)
}

def testToKebabCaseWithKebabCases: Property = for {
ss <- Gens.genPascalCase(1, 10).list(Range.linear(1, 5)).log("ss")
input <- Gen.constant(ss.mkString("-")).log("input")
} yield {
val expected = ss.mkString("-")
val actual = input.toKebabCase

val info =
s"""
|> input: $input
|> actual: $actual
|> expected: $expected
|""".stripMargin

(actual ==== expected).log(info)
}

def testToKebabCaseWithLowerKebabCases: Property = for {
ss <- Gen.string(Gen.lower, Range.linear(1, 10)).list(Range.linear(1, 5)).log("ss")
input <- Gen.constant(ss.mkString("-")).log("input")
} yield {
val expected = ss.mkString("-")
val actual = input.toKebabCase

val info =
s"""
|> input: $input
|> actual: $actual
|> expected: $expected
|""".stripMargin

(actual ==== expected).log(info)
}

def testToKebabCaseWithUpperKebabCases: Property = for {
ss <- Gen.string(Gen.upper, Range.linear(1, 10)).list(Range.linear(1, 5)).log("ss")
input <- Gen.constant(ss.mkString("-")).log("input")
} yield {
val expected = ss.mkString("-")
val actual = input.toKebabCase

val info =
s"""
|> input: $input
|> actual: $actual
|> expected: $expected
|""".stripMargin

(actual ==== expected).log(info)
}

def testToKebabCaseWithSpaceSeparatedStringValues: Property = for {
s <- Gens.genPascalCase(1, 10).log("ss")
ss <- Gens.genPascalCase(2, 10).list(Range.linear(1, 4)).log("ss")
input <- Gen.constant((s :: ss).mkString(" ")).log("input")
} yield {
val expected = (s :: ss).mkString("-")
val actual = input.toKebabCase

val info =
s"""
|> input: $input
|> actual: $actual
|> expected: $expected
|""".stripMargin

(actual ==== expected).log(info)
}

def testToKebabCaseWithLowerSpaceSeparatedStringValues: Property = for {
s <- Gen.string(Gen.lower, Range.linear(1, 10)).log("s")
ss <- Gen.string(Gen.lower, Range.linear(2, 10)).list(Range.linear(1, 5)).log("ss")
input <- Gen.constant((s :: ss).mkString(" ")).log("input")
} yield {
val expected = (s :: ss).mkString("-")
val actual = input.toKebabCase

val info =
s"""
|> input: $input
|> actual: $actual
|> expected: $expected
|""".stripMargin

(actual ==== expected).log(info)
}

def testToKebabCaseWithUpperSpaceSeparatedStringValues: Property = for {
s <- Gen.string(Gen.upper, Range.linear(1, 10)).log("s")
ss <- Gen.string(Gen.upper, Range.linear(2, 10)).list(Range.linear(1, 5)).log("ss")
input <- Gen.constant((s :: ss).mkString(" ")).log("input")
} yield {
val expected = (s :: ss).mkString("-")
val actual = input.toKebabCase

val info =
s"""
|> input: $input
|> actual: $actual
|> expected: $expected
|""".stripMargin

(actual ==== expected).log(info)
}
}

0 comments on commit 6575d8e

Please sign in to comment.