Skip to content

Commit ff07a4a

Browse files
authored
Merge pull request #206 from ashawley/utility-escape-test
Add tests for Utility.escape
2 parents 696eb3c + aed4cb3 commit ff07a4a

File tree

1 file changed

+130
-0
lines changed

1 file changed

+130
-0
lines changed

Diff for: shared/src/test/scala/scala/xml/UtilityTest.scala

+130
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ package scala.xml
33
import org.junit.Test
44
import org.junit.Assert.assertTrue
55
import org.junit.Assert.assertEquals
6+
import org.junit.Assert.assertNotEquals
67

78
class UtilityTest {
89

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

67+
val printableAscii: Seq[Char] = {
68+
(' ' to '/') ++ // Punctuation
69+
('0' to '9') ++ // Digits
70+
(':' to '@') ++ // Punctuation (cont.)
71+
('A' to 'Z') ++ // Uppercase
72+
('[' to '`') ++ // Punctuation (cont.)
73+
('a' to 'z') ++ // Lowercase
74+
('{' to '~') // Punctuation (cont.)
75+
}
76+
77+
val escapedChars: Seq[Char] =
78+
Utility.Escapes.escMap.keys.toSeq
79+
80+
@Test
81+
def escapePrintablesTest: Unit = {
82+
for {
83+
char <- (printableAscii.diff(escapedChars))
84+
} yield {
85+
assertEquals(char.toString, Utility.escape(char.toString))
86+
}
87+
}
88+
89+
@Test
90+
def escapeEscapablesTest: Unit = {
91+
for {
92+
char <- escapedChars
93+
} yield {
94+
assertNotEquals(char.toString, Utility.escape(char.toString))
95+
}
96+
}
97+
98+
@Test
99+
def escapeAsciiControlCharsTest: Unit = {
100+
101+
/* Escapes that Scala (Java) doesn't support.
102+
* \u0007 -> \a (bell)
103+
* \u001B -> \e (escape)
104+
* \u000B -> \v (vertical tab)
105+
* \u007F -> DEL (delete)
106+
*/
107+
val input = " \u0007\b\u001B\f\n\r\t\u000B\u007F"
108+
109+
val expect = " \n\r\t\u007F"
110+
111+
val result = Utility.escape(input)
112+
113+
assertEquals(printfc(expect), printfc(result)) // Pretty,
114+
assertEquals(expect, result) // but verify.
115+
}
116+
117+
@Test
118+
def escapeUnicodeExtendedControlCodesTest: Unit = {
119+
for {
120+
char <- ('\u0080' to '\u009f') // Extended control codes (C1)
121+
} yield {
122+
assertEquals(char.toString, Utility.escape(char.toString))
123+
}
124+
}
125+
126+
@Test
127+
def escapeUnicodeTwoBytesTest: Unit = {
128+
for {
129+
char <- ('\u00A0' to '\u07FF') // Two bytes (cont.)
130+
} yield {
131+
assertEquals(char.toString, Utility.escape(char.toString))
132+
}
133+
}
134+
135+
@Test
136+
def escapeUnicodeThreeBytesTest: Unit = {
137+
for {
138+
char <- ('\u0800' to '\uFFFF') // Three bytes
139+
} yield {
140+
assertEquals(char.toString, Utility.escape(char.toString))
141+
}
142+
}
143+
144+
/**
145+
* Human-readable character printing
146+
*
147+
* Think of `od -c` of unix od(1) command.
148+
*
149+
* Or think of `printf("%c", i)` in C, but a little better.
150+
*/
151+
def printfc(str: String) = {
152+
str.map(prettyChar).mkString
153+
}
154+
155+
/**
156+
* Visual representation of characters that enhances output of
157+
* failed test assertions.
158+
*/
159+
val prettyChar: Map[Char,String] = Map(
160+
'\u0000' -> "\\0", // Null
161+
'\u0001' -> "^A", // Start of header
162+
'\u0002' -> "^B", // Start of text
163+
'\u0003' -> "^C", // End of text
164+
'\u0004' -> "^D", // End of transmission
165+
'\u0005' -> "^E", // Enquiry
166+
'\u0006' -> "^F", // Acknowledgment
167+
'\u0007' -> "\\a", // Bell (^G)
168+
'\b' -> "\\b", // Backspace (^H)
169+
'\t' -> "\\t", // Tab (^I)
170+
'\n' -> "\\n", // Newline (^J)
171+
'\u000B' -> "\\v", // Vertical tab (^K)
172+
'\f' -> "\\f", // Form feed (^L)
173+
'\r' -> "\\r", // Carriage return (^M)
174+
'\u000E' -> "^N", // Shift out
175+
'\u000F' -> "^O", // Shift in
176+
'\u0010' -> "^P", // Data link escape
177+
'\u0011' -> "^Q", // DC1 (XON)
178+
'\u0012' -> "^R", // DC2
179+
'\u0013' -> "^S", // DC3 (XOFF)
180+
'\u0014' -> "^T", // DC4
181+
'\u0015' -> "^U", // Negative acknowledgment
182+
'\u0016' -> "^V", // Synchronous idle
183+
'\u0017' -> "^W", // End of transmission block
184+
'\u0018' -> "^X", // Cancel
185+
'\u0019' -> "^Y", // End of medium
186+
'\u001A' -> "^Z", // Substitute
187+
'\u001B' -> "\\e", // Escape
188+
'\u001C' -> "^\\", // File separator
189+
'\u001D' -> "^]", // Group separator
190+
'\u001E' -> "^^", // Record separator
191+
'\u001F' -> "^_", // Unit separator
192+
'\u007F' -> "^?" // Delete
193+
).toMap.withDefault {
194+
key: Char => key.toString
195+
}
66196
}

0 commit comments

Comments
 (0)