Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
130 changes: 130 additions & 0 deletions shared/src/test/scala/scala/xml/UtilityTest.scala
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package scala.xml
import org.junit.Test
import org.junit.Assert.assertTrue
import org.junit.Assert.assertEquals
import org.junit.Assert.assertNotEquals

class UtilityTest {

Expand Down Expand Up @@ -63,4 +64,133 @@ class UtilityTest {
assertEquals("<node><!-- comment --></node>", Utility.serialize(x, stripComments = false).toString)
}

val printableAscii: Seq[Char] = {
(' ' to '/') ++ // Punctuation
('0' to '9') ++ // Digits
(':' to '@') ++ // Punctuation (cont.)
('A' to 'Z') ++ // Uppercase
('[' to '`') ++ // Punctuation (cont.)
('a' to 'z') ++ // Lowercase
('{' to '~') // Punctuation (cont.)
}

val escapedChars: Seq[Char] =
Utility.Escapes.escMap.keys.toSeq

@Test
def escapePrintablesTest: Unit = {
for {
char <- (printableAscii.diff(escapedChars))
} yield {
assertEquals(char.toString, Utility.escape(char.toString))
}
}

@Test
def escapeEscapablesTest: Unit = {
for {
char <- escapedChars
} yield {
assertNotEquals(char.toString, Utility.escape(char.toString))
}
}

@Test
def escapeAsciiControlCharsTest: Unit = {

/* Escapes that Scala (Java) doesn't support.
* \u0007 -> \a (bell)
* \u001B -> \e (escape)
* \u000B -> \v (vertical tab)
* \u007F -> DEL (delete)
*/
val input = " \u0007\b\u001B\f\n\r\t\u000B\u007F"

val expect = " \n\r\t\u007F"

val result = Utility.escape(input)

assertEquals(printfc(expect), printfc(result)) // Pretty,
assertEquals(expect, result) // but verify.
}

@Test
def escapeUnicodeExtendedControlCodesTest: Unit = {
for {
char <- ('\u0080' to '\u009f') // Extended control codes (C1)
} yield {
assertEquals(char.toString, Utility.escape(char.toString))
}
}

@Test
def escapeUnicodeTwoBytesTest: Unit = {
for {
char <- ('\u00A0' to '\u07FF') // Two bytes (cont.)
} yield {
assertEquals(char.toString, Utility.escape(char.toString))
}
}

@Test
def escapeUnicodeThreeBytesTest: Unit = {
for {
char <- ('\u0800' to '\uFFFF') // Three bytes
} yield {
assertEquals(char.toString, Utility.escape(char.toString))
}
}

/**
* Human-readable character printing
*
* Think of `od -c` of unix od(1) command.
*
* Or think of `printf("%c", i)` in C, but a little better.
*/
def printfc(str: String) = {
str.map(prettyChar).mkString
}

/**
* Visual representation of characters that enhances output of
* failed test assertions.
*/
val prettyChar: Map[Char,String] = Map(
'\u0000' -> "\\0", // Null
'\u0001' -> "^A", // Start of header
'\u0002' -> "^B", // Start of text
'\u0003' -> "^C", // End of text
'\u0004' -> "^D", // End of transmission
'\u0005' -> "^E", // Enquiry
'\u0006' -> "^F", // Acknowledgment
'\u0007' -> "\\a", // Bell (^G)
'\b' -> "\\b", // Backspace (^H)
'\t' -> "\\t", // Tab (^I)
'\n' -> "\\n", // Newline (^J)
'\u000B' -> "\\v", // Vertical tab (^K)
'\f' -> "\\f", // Form feed (^L)
'\r' -> "\\r", // Carriage return (^M)
'\u000E' -> "^N", // Shift out
'\u000F' -> "^O", // Shift in
'\u0010' -> "^P", // Data link escape
'\u0011' -> "^Q", // DC1 (XON)
'\u0012' -> "^R", // DC2
'\u0013' -> "^S", // DC3 (XOFF)
'\u0014' -> "^T", // DC4
'\u0015' -> "^U", // Negative acknowledgment
'\u0016' -> "^V", // Synchronous idle
'\u0017' -> "^W", // End of transmission block
'\u0018' -> "^X", // Cancel
'\u0019' -> "^Y", // End of medium
'\u001A' -> "^Z", // Substitute
'\u001B' -> "\\e", // Escape
'\u001C' -> "^\\", // File separator
'\u001D' -> "^]", // Group separator
'\u001E' -> "^^", // Record separator
'\u001F' -> "^_", // Unit separator
'\u007F' -> "^?" // Delete
).toMap.withDefault {
key: Char => key.toString
}
}