diff options
author | 2017-05-01 19:00:58 +0200 | |
---|---|---|
committer | 2017-05-02 11:25:51 +0200 | |
commit | 5da0dd559885e3175e28b9d4b11fc6408939f211 (patch) | |
tree | 24929477d3b1119e1df13ddd0e50a00a56cdb59d /src/test/java | |
parent | 248581e8c72687c85b5c41edaea6780c8701aa55 (diff) |
Roll forward of https://github.com/bazelbuild/bazel/commit/5f31944b8942818aaf53571c76f5c6a9a9dafc72: Custom module map for j2objc_library
Automated g4 rollback of commit e7fe50aa727df9ef0a3d37fa258d017971035515.
*** Reason for rollback ***
Roll forward. The bzl change is removed because it has to be submitted after next Blaze release.
*** Original change description ***
Automated g4 rollback of commit 5f31944b8942818aaf53571c76f5c6a9a9dafc72.
*** Reason for rollback ***
This caused some build breaks.
*** Original change description ***
Custom module map for j2objc_library
PiperOrigin-RevId: 154726197
Diffstat (limited to 'src/test/java')
4 files changed, 181 insertions, 270 deletions
diff --git a/src/test/java/com/google/devtools/build/lib/bazel/rules/android/ndkcrosstools/ndk12bfiles.txt b/src/test/java/com/google/devtools/build/lib/bazel/rules/android/ndkcrosstools/ndk12bfiles.txt index 068f9613c4..e53209b2de 100644 --- a/src/test/java/com/google/devtools/build/lib/bazel/rules/android/ndkcrosstools/ndk12bfiles.txt +++ b/src/test/java/com/google/devtools/build/lib/bazel/rules/android/ndkcrosstools/ndk12bfiles.txt @@ -1,4 +1,32 @@ -thread.thread.class/types.pass.cpp +hread.req.lockable/thread.req.lockable.req/nothing_to_do.pass.cpp +sources/cxx-stl/llvm-libc++/libcxx/test/thread/thread.req/thread.req.lockable/thread.req.lockable.timed/nothing_to_do.pass.cpp +sources/cxx-stl/llvm-libc++/libcxx/test/thread/thread.req/thread.req.native/nothing_to_do.pass.cpp +sources/cxx-stl/llvm-libc++/libcxx/test/thread/thread.req/thread.req.paramname/nothing_to_do.pass.cpp +sources/cxx-stl/llvm-libc++/libcxx/test/thread/thread.req/thread.req.timing/nothing_to_do.pass.cpp +sources/cxx-stl/llvm-libc++/libcxx/test/thread/thread.threads/thread.thread.class/thread.thread.algorithm/swap.pass.cpp +sources/cxx-stl/llvm-libc++/libcxx/test/thread/thread.threads/thread.thread.class/thread.thread.assign/copy.fail.cpp +sources/cxx-stl/llvm-libc++/libcxx/test/thread/thread.threads/thread.thread.class/thread.thread.assign/move.pass.cpp +sources/cxx-stl/llvm-libc++/libcxx/test/thread/thread.threads/thread.thread.class/thread.thread.constr/constr.fail.cpp +sources/cxx-stl/llvm-libc++/libcxx/test/thread/thread.threads/thread.thread.class/thread.thread.constr/copy.fail.cpp +sources/cxx-stl/llvm-libc++/libcxx/test/thread/thread.threads/thread.thread.class/thread.thread.constr/default.pass.cpp +sources/cxx-stl/llvm-libc++/libcxx/test/thread/thread.threads/thread.thread.class/thread.thread.constr/F.pass.cpp +sources/cxx-stl/llvm-libc++/libcxx/test/thread/thread.threads/thread.thread.class/thread.thread.constr/move.pass.cpp +sources/cxx-stl/llvm-libc++/libcxx/test/thread/thread.threads/thread.thread.class/thread.thread.destr/dtor.pass.cpp +sources/cxx-stl/llvm-libc++/libcxx/test/thread/thread.threads/thread.thread.class/thread.thread.id/assign.pass.cpp +sources/cxx-stl/llvm-libc++/libcxx/test/thread/thread.threads/thread.thread.class/thread.thread.id/copy.pass.cpp +sources/cxx-stl/llvm-libc++/libcxx/test/thread/thread.threads/thread.thread.class/thread.thread.id/default.pass.cpp +sources/cxx-stl/llvm-libc++/libcxx/test/thread/thread.threads/thread.thread.class/thread.thread.id/eq.pass.cpp +sources/cxx-stl/llvm-libc++/libcxx/test/thread/thread.threads/thread.thread.class/thread.thread.id/lt.pass.cpp +sources/cxx-stl/llvm-libc++/libcxx/test/thread/thread.threads/thread.thread.class/thread.thread.id/stream.pass.cpp +sources/cxx-stl/llvm-libc++/libcxx/test/thread/thread.threads/thread.thread.class/thread.thread.id/thread_id.pass.cpp +sources/cxx-stl/llvm-libc++/libcxx/test/thread/thread.threads/thread.thread.class/thread.thread.member/detach.pass.cpp +sources/cxx-stl/llvm-libc++/libcxx/test/thread/thread.threads/thread.thread.class/thread.thread.member/get_id.pass.cpp +sources/cxx-stl/llvm-libc++/libcxx/test/thread/thread.threads/thread.thread.class/thread.thread.member/joinable.pass.cpp +sources/cxx-stl/llvm-libc++/libcxx/test/thread/thread.threads/thread.thread.class/thread.thread.member/join.pass.cpp +sources/cxx-stl/llvm-libc++/libcxx/test/thread/thread.threads/thread.thread.class/thread.thread.member/native_handle.pass.cpp +sources/cxx-stl/llvm-libc++/libcxx/test/thread/thread.threads/thread.thread.class/thread.thread.member/swap.pass.cpp +sources/cxx-stl/llvm-libc++/libcxx/test/thread/thread.threads/thread.thread.class/thread.thread.static/hardware_concurrency.pass.cpp +sources/cxx-stl/llvm-libc++/libcxx/test/thread/thread.threads/thread.thread.class/types.pass.cpp sources/cxx-stl/llvm-libc++/libcxx/test/thread/thread.threads/thread.thread.this/get_id.pass.cpp sources/cxx-stl/llvm-libc++/libcxx/test/thread/thread.threads/thread.thread.this/sleep_for.pass.cpp sources/cxx-stl/llvm-libc++/libcxx/test/thread/thread.threads/thread.thread.this/sleep_until.pass.cpp diff --git a/src/test/java/com/google/devtools/build/lib/bazel/rules/android/ndkcrosstools/ndkfiles.txt b/src/test/java/com/google/devtools/build/lib/bazel/rules/android/ndkcrosstools/ndkfiles.txt index ad209a867c..3fc3e9f482 100644 --- a/src/test/java/com/google/devtools/build/lib/bazel/rules/android/ndkcrosstools/ndkfiles.txt +++ b/src/test/java/com/google/devtools/build/lib/bazel/rules/android/ndkcrosstools/ndkfiles.txt @@ -1,4 +1,62 @@ --21/arch-x86_64/usr/lib64/libc.so +m.h +platforms/android-21/arch-x86_64/usr/include/sys/sendfile.h +platforms/android-21/arch-x86_64/usr/include/sys/shm.h +platforms/android-21/arch-x86_64/usr/include/sys/signalfd.h +platforms/android-21/arch-x86_64/usr/include/sys/signal.h +platforms/android-21/arch-x86_64/usr/include/sys/socketcalls.h +platforms/android-21/arch-x86_64/usr/include/sys/socket.h +platforms/android-21/arch-x86_64/usr/include/sys/statfs.h +platforms/android-21/arch-x86_64/usr/include/sys/stat.h +platforms/android-21/arch-x86_64/usr/include/sys/statvfs.h +platforms/android-21/arch-x86_64/usr/include/sys/swap.h +platforms/android-21/arch-x86_64/usr/include/sys/syscall.h +platforms/android-21/arch-x86_64/usr/include/sys/sysconf.h +platforms/android-21/arch-x86_64/usr/include/sys/sysinfo.h +platforms/android-21/arch-x86_64/usr/include/sys/syslimits.h +platforms/android-21/arch-x86_64/usr/include/sys/sysmacros.h +platforms/android-21/arch-x86_64/usr/include/sys/system_properties.h +platforms/android-21/arch-x86_64/usr/include/sys/time.h +platforms/android-21/arch-x86_64/usr/include/sys/timerfd.h +platforms/android-21/arch-x86_64/usr/include/sys/times.h +platforms/android-21/arch-x86_64/usr/include/sys/timex.h +platforms/android-21/arch-x86_64/usr/include/sys/ttychars.h +platforms/android-21/arch-x86_64/usr/include/sys/ttydefaults.h +platforms/android-21/arch-x86_64/usr/include/sys/ttydev.h +platforms/android-21/arch-x86_64/usr/include/sys/types.h +platforms/android-21/arch-x86_64/usr/include/sys/ucontext.h +platforms/android-21/arch-x86_64/usr/include/sys/uio.h +platforms/android-21/arch-x86_64/usr/include/sys/un.h +platforms/android-21/arch-x86_64/usr/include/sys/user.h +platforms/android-21/arch-x86_64/usr/include/sys/utime.h +platforms/android-21/arch-x86_64/usr/include/sys/utsname.h +platforms/android-21/arch-x86_64/usr/include/sys/vfs.h +platforms/android-21/arch-x86_64/usr/include/sys/vt.h +platforms/android-21/arch-x86_64/usr/include/sys/wait.h +platforms/android-21/arch-x86_64/usr/include/sys/xattr.h +platforms/android-21/arch-x86_64/usr/include/termio.h +platforms/android-21/arch-x86_64/usr/include/termios.h +platforms/android-21/arch-x86_64/usr/include/thread_db.h +platforms/android-21/arch-x86_64/usr/include/time64.h +platforms/android-21/arch-x86_64/usr/include/time.h +platforms/android-21/arch-x86_64/usr/include/uchar.h +platforms/android-21/arch-x86_64/usr/include/ucontext.h +platforms/android-21/arch-x86_64/usr/include/unistd.h +platforms/android-21/arch-x86_64/usr/include/util.h +platforms/android-21/arch-x86_64/usr/include/utime.h +platforms/android-21/arch-x86_64/usr/include/utmp.h +platforms/android-21/arch-x86_64/usr/include/wchar.h +platforms/android-21/arch-x86_64/usr/include/wctype.h +platforms/android-21/arch-x86_64/usr/include/xlocale.h +platforms/android-21/arch-x86_64/usr/include/zconf.h +platforms/android-21/arch-x86_64/usr/include/zlib.h +platforms/android-21/arch-x86_64/usr/lib64/crtbegin_dynamic.o +platforms/android-21/arch-x86_64/usr/lib64/crtbegin_so.o +platforms/android-21/arch-x86_64/usr/lib64/crtbegin_static.o +platforms/android-21/arch-x86_64/usr/lib64/crtend_android.o +platforms/android-21/arch-x86_64/usr/lib64/crtend_so.o +platforms/android-21/arch-x86_64/usr/lib64/libandroid.so +platforms/android-21/arch-x86_64/usr/lib64/libc.a +platforms/android-21/arch-x86_64/usr/lib64/libc.so platforms/android-21/arch-x86_64/usr/lib64/libdl.so platforms/android-21/arch-x86_64/usr/lib64/libEGL.so platforms/android-21/arch-x86_64/usr/lib64/libGLESv1_CM.so diff --git a/src/test/java/com/google/devtools/build/lib/packages/GlobCacheTest.java b/src/test/java/com/google/devtools/build/lib/packages/GlobCacheTest.java index 5b9beafeaa..30011adc1b 100644 --- a/src/test/java/com/google/devtools/build/lib/packages/GlobCacheTest.java +++ b/src/test/java/com/google/devtools/build/lib/packages/GlobCacheTest.java @@ -1,270 +1,4 @@ -// Copyright 2015 The Bazel Authors. All rights reserved. -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. -package com.google.devtools.build.lib.packages; - -import static com.google.common.truth.Truth.assertThat; -import static org.junit.Assert.fail; - -import com.google.common.collect.Lists; -import com.google.devtools.build.lib.cmdline.PackageIdentifier; -import com.google.devtools.build.lib.packages.Globber.BadGlobException; -import com.google.devtools.build.lib.testutil.Scratch; -import com.google.devtools.build.lib.testutil.TestUtils; -import com.google.devtools.build.lib.util.Pair; -import com.google.devtools.build.lib.vfs.FileSystemUtils; -import com.google.devtools.build.lib.vfs.Path; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.Collection; -import java.util.Collections; -import java.util.List; -import org.junit.After; -import org.junit.Before; -import org.junit.Test; -import org.junit.runner.RunWith; -import org.junit.runners.JUnit4; - -/** - * Tests for {@link GlobCache} - */ -@RunWith(JUnit4.class) -public class GlobCacheTest { - - private static final List<String> NONE = Collections.emptyList(); - - private Scratch scratch = new Scratch("/workspace"); - - private Path packageDirectory; - private Path buildFile; - private GlobCache cache; - - @Before - public final void createFiles() throws Exception { - buildFile = scratch.file("isolated/BUILD", - "# contents don't matter in this test"); - scratch.file("isolated/sub/BUILD", - "# contents don't matter in this test"); - - packageDirectory = buildFile.getParentDirectory(); - - scratch.file("isolated/first.txt", - "# this is first.txt"); - - scratch.file("isolated/second.txt", - "# this is second.txt"); - - scratch.file("isolated/first.js", - "# this is first.js"); - - scratch.file("isolated/second.js", - "# this is second.js"); - - // Files in subdirectories - - scratch.file("isolated/foo/first.js", - "# this is foo/first.js"); - - scratch.file("isolated/foo/second.js", - "# this is foo/second.js"); - - scratch.file("isolated/bar/first.js", - "# this is bar/first.js"); - - scratch.file("isolated/bar/second.js", - "# this is bar/second.js"); - - scratch.file("isolated/sub/sub.js", - "# this is sub/sub.js"); - - cache = - new GlobCache( - packageDirectory, - PackageIdentifier.createInMainRepo("isolated"), - new CachingPackageLocator() { - @Override - public Path getBuildFileForPackage(PackageIdentifier packageId) { - String packageName = packageId.getPackageFragment().getPathString(); - if (packageName.equals("isolated")) { - return scratch.resolve("isolated/BUILD"); - } else if (packageName.equals("isolated/sub")) { - return scratch.resolve("isolated/sub/BUILD"); - } else { - return null; - } - } - }, - null, - TestUtils.getPool(), - -1); - } - - @After - public final void deleteFiles() throws Exception { - FileSystemUtils.deleteTreesBelow(scratch.getFileSystem().getRootDirectory()); - } - - @Test - public void testSafeGlob() throws Exception { - List<Path> paths = cache.safeGlobUnsorted("*.js", false).get(); - assertPathsAre(paths, - "/workspace/isolated/first.js", "/workspace/isolated/second.js"); - } - - @Test - public void testSafeGlobInvalidPatterns() throws Exception { - for (String pattern : new String[] {"Foo?.txt", "List{Test}.py"}) { - try { - cache.safeGlobUnsorted(pattern, false); - fail("Expected pattern " + pattern + " to fail"); - } catch (BadGlobException expected) { - } - } - } - - @Test - public void testGetGlob() throws Exception { - List<String> glob = cache.getGlobUnsorted("*.js"); - assertThat(glob).containsExactly("first.js", "second.js"); - } - - @Test - public void testGetGlob_subdirectory() throws Exception { - List<String> glob = cache.getGlobUnsorted("foo/*.js"); - assertThat(glob).containsExactly("foo/first.js", "foo/second.js"); - } - - @Test - public void testGetKeySet() throws Exception { - assertThat(cache.getKeySet()).isEmpty(); - - cache.getGlobUnsorted("*.java"); - assertThat(cache.getKeySet()).containsExactly(Pair.of("*.java", false)); - - cache.getGlobUnsorted("*.java"); - assertThat(cache.getKeySet()).containsExactly(Pair.of("*.java", false)); - - cache.getGlobUnsorted("*.js"); - assertThat(cache.getKeySet()).containsExactly(Pair.of("*.java", false), Pair.of("*.js", false)); - - cache.getGlobUnsorted("*.java", true); - assertThat(cache.getKeySet()).containsExactly(Pair.of("*.java", false), Pair.of("*.js", false), - Pair.of("*.java", true)); - - try { - cache.getGlobUnsorted("invalid?"); - fail("Expected an invalid regex exception"); - } catch (BadGlobException expected) { - } - assertThat(cache.getKeySet()).containsExactly(Pair.of("*.java", false), Pair.of("*.js", false), - Pair.of("*.java", true)); - - cache.getGlobUnsorted("foo/first.*"); - assertThat(cache.getKeySet()).containsExactly(Pair.of("*.java", false), Pair.of("*.java", true), - Pair.of("*.js", false), Pair.of("foo/first.*", false)); - } - - @Test - public void testGlob() throws Exception { - assertEmpty(cache.globUnsorted(list("*.java"), NONE, false)); - - assertThat(cache.globUnsorted(list("*.*"), NONE, false)).containsExactly( - "first.js", "first.txt", "second.js", "second.txt"); - - assertThat(cache.globUnsorted(list("*.*"), list("first.js"), false)).containsExactly( - "first.txt", "second.js", "second.txt"); - - assertThat(cache.globUnsorted(list("*.txt", "first.*"), NONE, false)).containsExactly( - "first.txt", "second.txt", "first.js"); - } - - @Test - public void testRecursiveGlobDoesNotMatchSubpackage() throws Exception { - List<String> glob = cache.getGlobUnsorted("**/*.js"); - assertThat(glob).containsExactly("first.js", "second.js", "foo/first.js", "bar/first.js", - "foo/second.js", "bar/second.js"); - } - - @Test - public void testSingleFileExclude_Star() throws Exception { - assertThat(cache.globUnsorted(list("*"), list("first.txt"), false)).containsExactly( - "BUILD", "bar", "first.js", "foo", "second.js", "second.txt"); - } - - @Test - public void testSingleFileExclude_StarStar() throws Exception { - assertThat(cache.globUnsorted(list("**"), list("first.txt"), false)).containsExactly( - "BUILD", "bar", "bar/first.js", "bar/second.js", "first.js", "foo", "foo/first.js", - "foo/second.js", "second.js", "second.txt"); - } - - @Test - public void testExcludeAll_Star() throws Exception { - assertThat(cache.globUnsorted(list("*"), list("*"), false)).isEmpty(); - } - - @Test - public void testExcludeAll_Star_NoMatchesAnyway() throws Exception { - assertThat(cache.globUnsorted(list("nope"), list("*"), false)).isEmpty(); - } - - @Test - public void testExcludeAll_StarStar() throws Exception { - assertThat(cache.globUnsorted(list("**"), list("**"), false)).isEmpty(); - } - - @Test - public void testExcludeAll_Manual() throws Exception { - assertThat(cache.globUnsorted(list("**"), list("*", "*/*", "*/*/*"), false)).isEmpty(); - } - - @Test - public void testSingleFileExcludeDoesntMatch() throws Exception { - assertThat(cache.globUnsorted(list("first.txt"), list("nope.txt"), false)).containsExactly( - "first.txt"); - } - - @Test - public void testExcludeDirectory() throws Exception { - assertThat(cache.globUnsorted(list("foo/*"), NONE, true)).containsExactly( - "foo/first.js", "foo/second.js"); - assertThat(cache.globUnsorted(list("foo/*"), list("foo"), false)).containsExactly( - "foo/first.js", "foo/second.js"); - } - - @Test - public void testChildGlobWithChildExclude() throws Exception { - assertThat(cache.globUnsorted(list("foo/*"), list("foo/*"), false)).isEmpty(); - assertThat( - cache.globUnsorted(list("foo/first.js", "foo/second.js"), list("foo/*"), false)).isEmpty(); - assertThat(cache.globUnsorted(list("foo/first.js"), list("foo/first.js"), false)).isEmpty(); - assertThat(cache.globUnsorted(list("foo/first.js"), list("*/first.js"), false)).isEmpty(); - assertThat(cache.globUnsorted(list("foo/first.js"), list("*/*"), false)).isEmpty(); - } - - private void assertEmpty(Collection<?> glob) { - assertThat(glob).isEmpty(); - } - - private void assertPathsAre(List<Path> paths, String... strings) { - List<String> pathStrings = new ArrayList<>(); - for (Path path : paths) { - pathStrings.add(path.getPathString()); - } - assertThat(pathStrings).containsExactlyElementsIn(Arrays.asList(strings)); - } - - /* syntactic shorthand for Lists.newArrayList(strings) */ +syntactic shorthand for Lists.newArrayList(strings) */ private List<String> list(String... strings) { return Lists.newArrayList(strings); } diff --git a/src/test/java/com/google/devtools/build/lib/packages/ImplicitOutputsFunctionTest.java b/src/test/java/com/google/devtools/build/lib/packages/ImplicitOutputsFunctionTest.java index f19a31ee1d..321562475f 100644 --- a/src/test/java/com/google/devtools/build/lib/packages/ImplicitOutputsFunctionTest.java +++ b/src/test/java/com/google/devtools/build/lib/packages/ImplicitOutputsFunctionTest.java @@ -1,4 +1,95 @@ -{ +// Copyright 2015 The Bazel Authors. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +package com.google.devtools.build.lib.packages; + +import static com.google.common.truth.Truth.assertThat; +import static org.junit.Assert.assertEquals; + +import com.google.common.collect.ImmutableList; +import com.google.common.collect.ImmutableMap; +import com.google.devtools.build.lib.packages.ImplicitOutputsFunction.AttributeValueGetter; +import com.google.devtools.build.lib.testutil.Suite; +import com.google.devtools.build.lib.testutil.TestSpec; +import com.google.devtools.build.lib.util.Preconditions; + +import org.junit.Test; +import org.junit.runner.RunWith; +import org.junit.runners.JUnit4; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collection; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; + +/** + * Tests for {@link ImplicitOutputsFunction}. + */ +@TestSpec(size = Suite.SMALL_TESTS) +@RunWith(JUnit4.class) +public final class ImplicitOutputsFunctionTest { + private void assertPlaceholderCollection( + String template, String expectedTemplate, String... expectedPlaceholders) throws Exception { + List<String> actualPlaceholders = new ArrayList<>(); + assertEquals( + expectedTemplate, + ImplicitOutputsFunction.createPlaceholderSubstitutionFormatString( + template, actualPlaceholders)); + assertThat(actualPlaceholders) + .containsExactlyElementsIn(Arrays.asList(expectedPlaceholders)) + .inOrder(); + } + + @Test + public void testNoPlaceholder() throws Exception { + assertPlaceholderCollection("foo", "foo"); + } + + @Test + public void testJustPlaceholder() throws Exception { + assertPlaceholderCollection("%{foo}", "%s", "foo"); + } + + @Test + public void testPrefixedPlaceholder() throws Exception { + assertPlaceholderCollection("foo%{bar}", "foo%s", "bar"); + } + + @Test + public void testSuffixedPlaceholder() throws Exception { + assertPlaceholderCollection("%{foo}bar", "%sbar", "foo"); + } + + @Test + public void testMultiplePlaceholdersPrefixed() throws Exception { + assertPlaceholderCollection("foo%{bar}baz%{qux}", "foo%sbaz%s", "bar", "qux"); + } + + @Test + public void testMultiplePlaceholdersSuffixed() throws Exception { + assertPlaceholderCollection("%{foo}bar%{baz}qux", "%sbar%squx", "foo", "baz"); + } + + @Test + public void testTightlyPackedPlaceholders() throws Exception { + assertPlaceholderCollection("%{foo}%{bar}%{baz}", "%s%s%s", "foo", "bar", "baz"); + } + + @Test + public void testIncompletePlaceholder() throws Exception { assertPlaceholderCollection("%{foo", "%%{foo"); } |