aboutsummaryrefslogtreecommitdiffhomepage
path: root/src/test
diff options
context:
space:
mode:
authorGravatar laurentlb <laurentlb@google.com>2017-11-27 05:43:36 -0800
committerGravatar Copybara-Service <copybara-piper@google.com>2017-11-27 05:45:34 -0800
commitc83c12db5052a4be4bed29f8a9344c17a51aff3f (patch)
treed3e90cc6bd862075999dcea0749627186c4b99fd /src/test
parent0838aeeb545013c8261f0ae438f6027a78aea603 (diff)
Migrate some Skylark tests outside of Blaze.
RELNOTES: None. PiperOrigin-RevId: 177004853
Diffstat (limited to 'src/test')
-rw-r--r--src/test/java/com/google/devtools/build/lib/syntax/MethodLibraryTest.java353
-rw-r--r--src/test/skylark/testdata/all_any.sky46
-rw-r--r--src/test/skylark/testdata/string_partition.sky40
-rw-r--r--src/test/skylark/testdata/string_split.sky45
-rw-r--r--src/test/skylark/testdata/string_splitlines.sky29
-rw-r--r--src/test/skylark/testdata/string_test_characters.sky54
6 files changed, 214 insertions, 353 deletions
diff --git a/src/test/java/com/google/devtools/build/lib/syntax/MethodLibraryTest.java b/src/test/java/com/google/devtools/build/lib/syntax/MethodLibraryTest.java
index e57d8c8f79..a9a4b3861d 100644
--- a/src/test/java/com/google/devtools/build/lib/syntax/MethodLibraryTest.java
+++ b/src/test/java/com/google/devtools/build/lib/syntax/MethodLibraryTest.java
@@ -38,207 +38,6 @@ public class MethodLibraryTest extends EvaluationTestCase {
}
@Test
- public void testSplitLines_EmptyLine() throws Exception {
- new BothModesTest().testEval("''.splitlines()", "[]").testEval("'\\n'.splitlines()", "['']");
- }
-
- @Test
- public void testSplitLines_StartsWithLineBreak() throws Exception {
- new BothModesTest().testEval("'\\ntest'.splitlines()", "['', 'test']");
- }
-
- @Test
- public void testSplitLines_EndsWithLineBreak() throws Exception {
- new BothModesTest().testEval("'test\\n'.splitlines()", "['test']");
- }
-
- @Test
- public void testSplitLines_DifferentLineBreaks() throws Exception {
- new BothModesTest()
- .testEval("'this\\nis\\na\\ntest'.splitlines()", "['this', 'is', 'a', 'test']");
- }
-
- @Test
- public void testSplitLines_OnlyLineBreaks() throws Exception {
- new BothModesTest()
- .testEval("'\\n\\n\\n'.splitlines()", "['', '', '']")
- .testEval("'\\r\\r\\r'.splitlines()", "['', '', '']")
- .testEval("'\\n\\r\\n\\r'.splitlines()", "['', '', '']")
- .testEval("'\\r\\n\\r\\n\\r\\n'.splitlines()", "['', '', '']");
- }
-
- @Test
- public void testSplitLines_EscapedSequences() throws Exception {
- new BothModesTest().testEval("'\\n\\\\n\\\\\\n'.splitlines()", "['', '\\\\n\\\\']");
- }
-
- @Test
- public void testSplitLines_KeepEnds() throws Exception {
- new BothModesTest()
- .testEval("''.splitlines(True)", "[]")
- .testEval("'\\n'.splitlines(True)", "['\\n']")
- .testEval(
- "'this\\nis\\r\\na\\rtest'.splitlines(True)", "['this\\n', 'is\\r\\n', 'a\\r', 'test']")
- .testEval("'\\ntest'.splitlines(True)", "['\\n', 'test']")
- .testEval("'test\\n'.splitlines(True)", "['test\\n']")
- .testEval("'\\n\\\\n\\\\\\n'.splitlines(True)", "['\\n', '\\\\n\\\\\\n']");
- }
-
- @Test
- public void testStringIsAlnum() throws Exception {
- new BothModesTest()
- .testStatement("''.isalnum()", false)
- .testStatement("'a0 33'.isalnum()", false)
- .testStatement("'1'.isalnum()", true)
- .testStatement("'a033'.isalnum()", true);
- }
-
- @Test
- public void testStringIsDigit() throws Exception {
- new BothModesTest()
- .testStatement("''.isdigit()", false)
- .testStatement("' '.isdigit()", false)
- .testStatement("'a'.isdigit()", false)
- .testStatement("'0234325.33'.isdigit()", false)
- .testStatement("'1'.isdigit()", true)
- .testStatement("'033'.isdigit()", true);
- }
-
- @Test
- public void testStringIsSpace() throws Exception {
- new BothModesTest()
- .testStatement("''.isspace()", false)
- .testStatement("'a'.isspace()", false)
- .testStatement("'1'.isspace()", false)
- .testStatement("'\\ta\\n'.isspace()", false)
- .testStatement("' '.isspace()", true)
- .testStatement("'\\t\\n'.isspace()", true);
- }
-
- @Test
- public void testStringIsLower() throws Exception {
- new BothModesTest()
- .testStatement("''.islower()", false)
- .testStatement("' '.islower()", false)
- .testStatement("'1'.islower()", false)
- .testStatement("'Almost'.islower()", false)
- .testStatement("'abc'.islower()", true)
- .testStatement("' \\nabc'.islower()", true)
- .testStatement("'abc def\\n'.islower()", true)
- .testStatement("'\\ta\\n'.islower()", true);
- }
-
- @Test
- public void testStringIsUpper() throws Exception {
- new BothModesTest()
- .testStatement("''.isupper()", false)
- .testStatement("' '.isupper()", false)
- .testStatement("'1'.isupper()", false)
- .testStatement("'aLMOST'.isupper()", false)
- .testStatement("'ABC'.isupper()", true)
- .testStatement("' \\nABC'.isupper()", true)
- .testStatement("'ABC DEF\\n'.isupper()", true)
- .testStatement("'\\tA\\n'.isupper()", true);
- }
-
- @Test
- public void testStringIsTitle() throws Exception {
- new BothModesTest()
- .testStatement("''.istitle()", false)
- .testStatement("' '.istitle()", false)
- .testStatement("'134'.istitle()", false)
- .testStatement("'almost Correct'.istitle()", false)
- .testStatement("'1nope Nope Nope'.istitle()", false)
- .testStatement("'NO Way'.istitle()", false)
- .testStatement("'T'.istitle()", true)
- .testStatement("'Correct'.istitle()", true)
- .testStatement("'Very Correct! Yes\\nIndeed1X'.istitle()", true)
- .testStatement("'1234Ab Ab'.istitle()", true)
- .testStatement("'\\tA\\n'.istitle()", true);
- }
-
- @Test
- public void testAllWithEmptyValue() throws Exception {
- new BothModesTest()
- .testStatement("all('')", true)
- .testStatement("all([])", true)
- .testIfExactError("type 'NoneType' is not iterable", "any(None)");
- }
-
- @Test
- public void testAllWithPrimitiveType() throws Exception {
- new BothModesTest().testStatement("all('test')", true).testIfErrorContains("", "all(1)");
- }
-
- @Test
- public void testAllWithList() throws Exception {
- new BothModesTest()
- .testStatement("all([False])", false)
- .testStatement("all([True, False])", false)
- .testStatement("all([False, False])", false)
- .testStatement("all([False, True])", false)
- .testStatement("all(['', True])", false)
- .testStatement("all([0, True])", false)
- .testStatement("all([[], True])", false)
- .testStatement("all([True, 't', 1])", true);
- }
-
- @Test
- public void testAllWithSet() throws Exception {
- new BothModesTest()
- .testStatement("all(depset([0]))", false)
- .testStatement("all(depset([1, 0]))", false)
- .testStatement("all(depset([1]))", true);
- }
-
- @Test
- public void testAllWithDict() throws Exception {
- new BothModesTest()
- .testStatement("all({1 : None})", true)
- .testStatement("all({None : 1})", false);
- }
-
- @Test
- public void testAnyWithEmptyValue() throws Exception {
- new BothModesTest()
- .testStatement("any('')", false)
- .testStatement("any([])", false)
- .testIfExactError("type 'NoneType' is not iterable", "any(None)");
- }
-
- @Test
- public void testAnyWithPrimitiveType() throws Exception {
- new BothModesTest().testStatement("any('test')", true).testIfErrorContains("", "any(1)");
- }
-
- @Test
- public void testAnyWithList() throws Exception {
- new BothModesTest()
- .testStatement("any([False])", false)
- .testStatement("any([0])", false)
- .testStatement("any([''])", false)
- .testStatement("any([[]])", false)
- .testStatement("any([True, False])", true)
- .testStatement("any([False, False])", false)
- .testStatement("any([False, '', 0])", false)
- .testStatement("any([False, '', 42])", true);
- }
-
- @Test
- public void testAnyWithSet() throws Exception {
- new BothModesTest()
- .testStatement("any(depset([0]))", false)
- .testStatement("any(depset([1, 0]))", true);
- }
-
- @Test
- public void testAnyWithDict() throws Exception {
- new BothModesTest()
- .testStatement("any({1 : None, '' : None})", true)
- .testStatement("any({None : 1, '' : 2})", false);
- }
-
- @Test
public void testStackTraceLocation() throws Exception {
new SkylarkTest()
.testIfErrorContains(
@@ -456,158 +255,6 @@ public class MethodLibraryTest extends EvaluationTestCase {
}
@Test
- public void testPyStringSplit() throws Exception {
- new BothModesTest().testEval("'h i'.split(' ')", "['h', 'i']");
- }
-
- @Test
- public void testPyStringSplit2() throws Exception {
- new BothModesTest().testEval("'h i p'.split(' ')", "['h', 'i', 'p']");
- }
-
- @Test
- public void testPyStringSplit3() throws Exception {
- new BothModesTest().testEval("'a,e,i,o,u'.split(',', 2)", "['a', 'e', 'i,o,u']");
- }
-
- @Test
- public void testPyStringSplitNoSep() throws Exception {
- new BothModesTest()
- .testEval("' 1 2 3 '.split(' ')", "['', '', '1', '', '2', '', '3', '', '']");
- }
-
- @Test
- public void testPyStringRSplitRegex() throws Exception {
- new BothModesTest()
- .testEval("'foo/bar.lisp'.rsplit('.')", "['foo/bar', 'lisp']")
- .testEval("'foo/bar.?lisp'.rsplit('.?')", "['foo/bar', 'lisp']")
- .testEval("'fwe$foo'.rsplit('$')", "['fwe', 'foo']")
- .testEval("'windows'.rsplit('\\w')", "['windows']");
- }
-
- @Test
- public void testPyStringRSplitNoMatch() throws Exception {
- new BothModesTest()
- .testEval("''.rsplit('o')", "['']")
- .testEval("'google'.rsplit('x')", "['google']");
- }
-
- @Test
- public void testPyStringRSplitSeparator() throws Exception {
- new BothModesTest()
- .testEval("'xxxxxx'.rsplit('x')", "['', '', '', '', '', '', '']")
- .testEval("'xxxxxx'.rsplit('x', 1)", "['xxxxx', '']")
- .testEval("'xxxxxx'.rsplit('x', 2)", "['xxxx', '', '']")
- .testEval("'xxxxxx'.rsplit('x', 3)", "['xxx', '', '', '']")
- .testEval("'xxxxxx'.rsplit('x', 4)", "['xx', '', '', '', '']")
- .testEval("'xxxxxx'.rsplit('x', 5)", "['x', '', '', '', '', '']")
- .testEval("'xxxxxx'.rsplit('x', 6)", "['', '', '', '', '', '', '']")
- .testEval("'xxxxxx'.rsplit('x', 7)", "['', '', '', '', '', '', '']");
- }
-
- @Test
- public void testPyStringRSplitLongerSep() throws Exception {
- new BothModesTest()
- .testEval("'abcdabef'.rsplit('ab')", "['', 'cd', 'ef']")
- .testEval("'google_or_gogol'.rsplit('go')", "['', 'ogle_or_', '', 'l']");
- }
-
- @Test
- public void testPyStringRSplitMaxSplit() throws Exception {
- new BothModesTest()
- .testEval("'google'.rsplit('o')", "['g', '', 'gle']")
- .testEval("'google'.rsplit('o')", "['g', '', 'gle']")
- .testEval("'google'.rsplit('o', 1)", "['go', 'gle']")
- .testEval("'google'.rsplit('o', 2)", "['g', '', 'gle']")
- .testEval("'google'.rsplit('o', 3)", "['g', '', 'gle']")
- .testEval("'ogooglo'.rsplit('o')", "['', 'g', '', 'gl', '']")
- .testEval("'ogooglo'.rsplit('o', 1)", "['ogoogl', '']")
- .testEval("'ogooglo'.rsplit('o', 2)", "['ogo', 'gl', '']")
- .testEval("'ogooglo'.rsplit('o', 3)", "['og', '', 'gl', '']")
- .testEval("'ogooglo'.rsplit('o', 4)", "['', 'g', '', 'gl', '']")
- .testEval("'ogooglo'.rsplit('o', 5)", "['', 'g', '', 'gl', '']")
- .testEval("'google'.rsplit('google')", "['', '']")
- .testEval("'google'.rsplit('google', 1)", "['', '']")
- .testEval("'google'.rsplit('google', 2)", "['', '']");
- }
-
- @Test
- public void testPyStringPartitionEasy() throws Exception {
- new BothModesTest()
- .testEval("'lawl'.partition('a')", "('l', 'a', 'wl')")
- .testEval("'lawl'.rpartition('a')", "('l', 'a', 'wl')");
- }
-
- @Test
- public void testPyStringPartitionMultipleSep() throws Exception {
- new BothModesTest()
- .testEval("'google'.partition('o')", "('g', 'o', 'ogle')")
- .testEval("'google'.rpartition('o')", "('go', 'o', 'gle')")
- .testEval("'xxx'.partition('x')", "('', 'x', 'xx')")
- .testEval("'xxx'.rpartition('x')", "('xx', 'x', '')");
- }
-
- @Test
- public void testPyStringPartitionEmptyInput() throws Exception {
- new BothModesTest()
- .testEval("''.partition('a')", "('', '', '')")
- .testEval("''.rpartition('a')", "('', '', '')");
- }
-
- @Test
- public void testPyStringPartitionEmptySeparator() throws Exception {
- new BothModesTest()
- .testIfErrorContains("Empty separator", "'google'.partition('')")
- .testIfErrorContains("Empty separator", "'google'.rpartition('')");
- }
-
- @Test
- public void testPyStringPartitionDefaultSep() throws Exception {
- new BothModesTest()
- .testEval("'hi this is a test'.partition()", "('hi', ' ', 'this is a test')")
- .testEval("'hi this is a test'.rpartition()", "('hi this is a', ' ', 'test')")
- .testEval("'google'.partition()", "('google', '', '')")
- .testEval("'google'.rpartition()", "('', '', 'google')");
- }
-
- @Test
- public void testPyStringPartitionNoMatch() throws Exception {
- new BothModesTest()
- .testEval("'google'.partition('x')", "('google', '', '')")
- .testEval("'google'.rpartition('x')", "('', '', 'google')");
- }
-
- @Test
- public void testPyStringPartitionWordBoundaries() throws Exception {
- new BothModesTest()
- .testEval("'goog'.partition('g')", "('', 'g', 'oog')")
- .testEval("'goog'.rpartition('g')", "('goo', 'g', '')")
- .testEval("'plex'.partition('p')", "('', 'p', 'lex')")
- .testEval("'plex'.rpartition('p')", "('', 'p', 'lex')")
- .testEval("'plex'.partition('x')", "('ple', 'x', '')")
- .testEval("'plex'.rpartition('x')", "('ple', 'x', '')");
- }
-
- @Test
- public void testPyStringPartitionLongSep() throws Exception {
- new BothModesTest()
- .testEval("'google'.partition('oog')", "('g', 'oog', 'le')")
- .testEval("'google'.rpartition('oog')", "('g', 'oog', 'le')")
- .testEval(
- "'lolgooglolgooglolgooglol'.partition('goog')", "('lol', 'goog', 'lolgooglolgooglol')")
- .testEval(
- "'lolgooglolgooglolgooglol'.rpartition('goog')",
- "('lolgooglolgooglol', 'goog', 'lol')");
- }
-
- @Test
- public void testPyStringPartitionCompleteString() throws Exception {
- new BothModesTest()
- .testEval("'google'.partition('google')", "('', 'google', '')")
- .testEval("'google'.rpartition('google')", "('', 'google', '')");
- }
-
- @Test
public void testPyStringTitle() throws Exception {
new BothModesTest()
.testStatement("'this is a very simple test'.title()", "This Is A Very Simple Test");
diff --git a/src/test/skylark/testdata/all_any.sky b/src/test/skylark/testdata/all_any.sky
new file mode 100644
index 0000000000..1b37967737
--- /dev/null
+++ b/src/test/skylark/testdata/all_any.sky
@@ -0,0 +1,46 @@
+# All with empty value
+assert_eq(all(''), True)
+assert_eq(all([]), True)
+
+# All with list
+assert_eq(all('test'), True)
+assert_eq(all([False]), False)
+assert_eq(all([True, False]), False)
+assert_eq(all([False, False]), False)
+assert_eq(all([False, True]), False)
+assert_eq(all(['', True]), False)
+assert_eq(all([0, True]), False)
+assert_eq(all([[], True]), False)
+assert_eq(all([True, 't', 1]), True)
+
+# All with dict
+assert_eq(all({1 : None}), True)
+assert_eq(all({None : 1}), False)
+
+# Any with empty value
+assert_eq(any(''), False)
+assert_eq(any([]), False)
+
+# Any with list
+assert_eq(any('test'), True)
+assert_eq(any([False]), False)
+assert_eq(any([0]), False)
+assert_eq(any(['']), False)
+assert_eq(any([[]]), False)
+assert_eq(any([True, False]), True)
+assert_eq(any([False, False]), False)
+assert_eq(any([False, '', 0]), False)
+assert_eq(any([False, '', 42]), True)
+
+# Any with dict
+assert_eq(any({1 : None, '' : None}), True)
+assert_eq(any({None : 1, '' : 2}), False)
+
+---
+all(None) ### type 'NoneType' is not iterable
+---
+any(None) ### type 'NoneType' is not iterable
+---
+any(1) ### type 'int' is not iterable
+---
+all(1) ### type 'int' is not iterable
diff --git a/src/test/skylark/testdata/string_partition.sky b/src/test/skylark/testdata/string_partition.sky
new file mode 100644
index 0000000000..dc2d5be942
--- /dev/null
+++ b/src/test/skylark/testdata/string_partition.sky
@@ -0,0 +1,40 @@
+assert_eq('lawl'.partition('a'), ('l', 'a', 'wl'))
+assert_eq('lawl'.rpartition('a'), ('l', 'a', 'wl'))
+assert_eq('google'.partition('o'), ('g', 'o', 'ogle'))
+assert_eq('google'.rpartition('o'), ('go', 'o', 'gle'))
+assert_eq('xxx'.partition('x'), ('', 'x', 'xx'))
+assert_eq('xxx'.rpartition('x'), ('xx', 'x', ''))
+assert_eq(''.partition('a'), ('', '', ''))
+assert_eq(''.rpartition('a'), ('', '', ''))
+
+# default separator
+assert_eq('hi this is a test'.partition(), ('hi', ' ', 'this is a test'))
+assert_eq('hi this is a test'.rpartition(), ('hi this is a', ' ', 'test'))
+assert_eq('google'.partition(), ('google', '', ''))
+assert_eq('google'.rpartition(), ('', '', 'google'))
+
+# no match
+assert_eq('google'.partition('x'), ('google', '', ''))
+assert_eq('google'.rpartition('x'), ('', '', 'google'))
+
+# at word boundaries
+assert_eq('goog'.partition('g'), ('', 'g', 'oog'))
+assert_eq('goog'.rpartition('g'), ('goo', 'g', ''))
+assert_eq('plex'.partition('p'), ('', 'p', 'lex'))
+assert_eq('plex'.rpartition('p'), ('', 'p', 'lex'))
+assert_eq('plex'.partition('x'), ('ple', 'x', ''))
+assert_eq('plex'.rpartition('x'), ('ple', 'x', ''))
+
+assert_eq('google'.partition('oog'), ('g', 'oog', 'le'))
+assert_eq('google'.rpartition('oog'), ('g', 'oog', 'le'))
+assert_eq('lolgooglolgooglolgooglol'.partition('goog'), ('lol', 'goog', 'lolgooglolgooglol'))
+assert_eq('lolgooglolgooglolgooglol'.rpartition('goog'), ('lolgooglolgooglol', 'goog', 'lol'))
+
+# full string
+assert_eq('google'.partition('google'), ('', 'google', ''))
+assert_eq('google'.rpartition('google'), ('', 'google', ''))
+
+---
+'google'.partition('') ### Empty separator
+---
+'google'.rpartition('') ### Empty separator
diff --git a/src/test/skylark/testdata/string_split.sky b/src/test/skylark/testdata/string_split.sky
new file mode 100644
index 0000000000..e8c5ba1022
--- /dev/null
+++ b/src/test/skylark/testdata/string_split.sky
@@ -0,0 +1,45 @@
+# split
+assert_eq('h i'.split(' '), ['h', 'i'])
+assert_eq('h i p'.split(' '), ['h', 'i', 'p'])
+assert_eq('a,e,i,o,u'.split(',', 2), ['a', 'e', 'i,o,u'])
+assert_eq(' 1 2 3 '.split(' '), ['', '', '1', '', '2', '', '3', '', ''])
+
+# rsplit
+assert_eq('abcdabef'.rsplit('ab'), ['', 'cd', 'ef'])
+assert_eq('google_or_gogol'.rsplit('go'), ['', 'ogle_or_', '', 'l'])
+
+# rsplit regex
+assert_eq('foo/bar.lisp'.rsplit('.'), ['foo/bar', 'lisp'])
+assert_eq('foo/bar.?lisp'.rsplit('.?'), ['foo/bar', 'lisp'])
+assert_eq('fwe$foo'.rsplit('$'), ['fwe', 'foo'])
+assert_eq('windows'.rsplit('\w'), ['windows'])
+
+# rsplit no match
+assert_eq(''.rsplit('o'), [''])
+assert_eq('google'.rsplit('x'), ['google'])
+
+# rsplit separator
+assert_eq('xxxxxx'.rsplit('x'), ['', '', '', '', '', '', ''])
+assert_eq('xxxxxx'.rsplit('x', 1), ['xxxxx', ''])
+assert_eq('xxxxxx'.rsplit('x', 2), ['xxxx', '', ''])
+assert_eq('xxxxxx'.rsplit('x', 3), ['xxx', '', '', ''])
+assert_eq('xxxxxx'.rsplit('x', 4), ['xx', '', '', '', ''])
+assert_eq('xxxxxx'.rsplit('x', 5), ['x', '', '', '', '', ''])
+assert_eq('xxxxxx'.rsplit('x', 6), ['', '', '', '', '', '', ''])
+assert_eq('xxxxxx'.rsplit('x', 7), ['', '', '', '', '', '', ''])
+
+# split max split
+assert_eq('google'.rsplit('o'), ['g', '', 'gle'])
+assert_eq('google'.rsplit('o'), ['g', '', 'gle'])
+assert_eq('google'.rsplit('o', 1), ['go', 'gle'])
+assert_eq('google'.rsplit('o', 2), ['g', '', 'gle'])
+assert_eq('google'.rsplit('o', 3), ['g', '', 'gle'])
+assert_eq('ogooglo'.rsplit('o'), ['', 'g', '', 'gl', ''])
+assert_eq('ogooglo'.rsplit('o', 1), ['ogoogl', ''])
+assert_eq('ogooglo'.rsplit('o', 2), ['ogo', 'gl', ''])
+assert_eq('ogooglo'.rsplit('o', 3), ['og', '', 'gl', ''])
+assert_eq('ogooglo'.rsplit('o', 4), ['', 'g', '', 'gl', ''])
+assert_eq('ogooglo'.rsplit('o', 5), ['', 'g', '', 'gl', ''])
+assert_eq('google'.rsplit('google'), ['', ''])
+assert_eq('google'.rsplit('google', 1), ['', ''])
+assert_eq('google'.rsplit('google', 2), ['', ''])
diff --git a/src/test/skylark/testdata/string_splitlines.sky b/src/test/skylark/testdata/string_splitlines.sky
new file mode 100644
index 0000000000..8590513f3a
--- /dev/null
+++ b/src/test/skylark/testdata/string_splitlines.sky
@@ -0,0 +1,29 @@
+# Empty line
+assert_eq(''.splitlines(), [])
+assert_eq('\n'.splitlines(), [''])
+
+# Starts with line break
+assert_eq('\ntest'.splitlines(), ['', 'test'])
+
+# Ends with line break
+assert_eq('test\n'.splitlines(), ['test'])
+
+# Different line breaks
+assert_eq('this\nis\na\ntest'.splitlines(), ['this', 'is', 'a', 'test'])
+
+# Only line breaks
+assert_eq('\n\n\n'.splitlines(), ['', '', ''])
+assert_eq('\r\r\r'.splitlines(), ['', '', ''])
+assert_eq('\n\r\n\r'.splitlines(), ['', '', ''])
+assert_eq('\r\n\r\n\r\n'.splitlines(), ['', '', ''])
+
+# Escaped sequences
+assert_eq('\n\\n\\\n'.splitlines(), ['', '\\n\\'])
+
+# KeepEnds
+assert_eq(''.splitlines(True), [])
+assert_eq('\n'.splitlines(True), ['\n'])
+assert_eq('this\nis\r\na\rtest'.splitlines(True), ['this\n', 'is\r\n', 'a\r', 'test'])
+assert_eq('\ntest'.splitlines(True), ['\n', 'test'])
+assert_eq('test\n'.splitlines(True), ['test\n'])
+assert_eq('\n\\n\\\n'.splitlines(True), ['\n', '\\n\\\n'])
diff --git a/src/test/skylark/testdata/string_test_characters.sky b/src/test/skylark/testdata/string_test_characters.sky
new file mode 100644
index 0000000000..df81d37573
--- /dev/null
+++ b/src/test/skylark/testdata/string_test_characters.sky
@@ -0,0 +1,54 @@
+# isalnum
+assert_eq(''.isalnum(), False)
+assert_eq('a0 33'.isalnum(), False)
+assert_eq('1'.isalnum(), True)
+assert_eq('a033'.isalnum(), True)
+
+# isdigit
+assert_eq(''.isdigit(), False)
+assert_eq(' '.isdigit(), False)
+assert_eq('a'.isdigit(), False)
+assert_eq('0234325.33'.isdigit(), False)
+assert_eq('1'.isdigit(), True)
+assert_eq('033'.isdigit(), True)
+
+# isspace
+assert_eq(''.isspace(), False)
+assert_eq('a'.isspace(), False)
+assert_eq('1'.isspace(), False)
+assert_eq('\ta\n'.isspace(), False)
+assert_eq(' '.isspace(), True)
+assert_eq('\t\n'.isspace(), True)
+
+# islower
+assert_eq(''.islower(), False)
+assert_eq(' '.islower(), False)
+assert_eq('1'.islower(), False)
+assert_eq('Almost'.islower(), False)
+assert_eq('abc'.islower(), True)
+assert_eq(' \nabc'.islower(), True)
+assert_eq('abc def\n'.islower(), True)
+assert_eq('\ta\n'.islower(), True)
+
+# isupper
+assert_eq(''.isupper(), False)
+assert_eq(' '.isupper(), False)
+assert_eq('1'.isupper(), False)
+assert_eq('aLMOST'.isupper(), False)
+assert_eq('ABC'.isupper(), True)
+assert_eq(' \nABC'.isupper(), True)
+assert_eq('ABC DEF\n'.isupper(), True)
+assert_eq('\tA\n'.isupper(), True)
+
+# istitle
+assert_eq(''.istitle(), False)
+assert_eq(' '.istitle(), False)
+assert_eq('134'.istitle(), False)
+assert_eq('almost Correct'.istitle(), False)
+assert_eq('1nope Nope Nope'.istitle(), False)
+assert_eq('NO Way'.istitle(), False)
+assert_eq('T'.istitle(), True)
+assert_eq('Correct'.istitle(), True)
+assert_eq('Very Correct! Yes\nIndeed1X'.istitle(), True)
+assert_eq('1234Ab Ab'.istitle(), True)
+assert_eq('\tA\n'.istitle(), True)