//
// Copyright © 2014, David Tesler (https://github.com/protobufel)
// All rights reserved.
//
// Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are met:
// * Redistributions of source code must retain the above copyright
// notice, this list of conditions and the following disclaimer.
// * Redistributions in binary form must reproduce the above copyright
// notice, this list of conditions and the following disclaimer in the
// documentation and/or other materials provided with the distribution.
// * Neither the name of the <organization> nor the
// names of its contributors may be used to endorse or promote products
// derived from this software without specific prior written permission.
//
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
// ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
// DISCLAIMED. IN NO EVENT SHALL <COPYRIGHT HOLDER> BE LIABLE FOR ANY
// DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
// LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
// ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
// SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
//
package com.github.protobufel.common.files;
import static com.github.protobufel.common.verifications.Verifications.assertNonNull;
import static com.github.protobufel.common.verifications.Verifications.verifyCondition;
import static org.hamcrest.CoreMatchers.equalTo;
import static org.hamcrest.CoreMatchers.is;
import static org.hamcrest.CoreMatchers.startsWith;
import static org.hamcrest.MatcherAssert.assertThat;
import static org.junit.Assume.assumeThat;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.junit.After;
import org.junit.Ignore;
import org.junit.Rule;
import org.junit.Test;
import org.junit.experimental.theories.DataPoints;
import org.junit.experimental.theories.FromDataPoints;
import org.junit.experimental.theories.Theories;
import org.junit.experimental.theories.Theory;
import org.junit.rules.TemporaryFolder;
import org.junit.runner.RunWith;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.github.protobufel.common.files.ContextPathMatchers.SimpleHierarchicalMatcher;
@RunWith(Theories.class)
public class GlobRegexTest {
@SuppressWarnings({ "unused", "null" })
private static final Logger log = LoggerFactory.getLogger(GlobRegexTest.class);
@DataPoints("globs")
public static final Object[] globs = new String[][] {
// "part1*/?part2?/*/part3{_1,_2,_3}/**/part4.extra/*.ext"
new String[] {"part1*/?part2?/*/part3{_1,_2,_3}/*/part4.extra/*.ext", "/part4.extra/1.ext1"}
};
@DataPoints("testPaths")
public static final String[] testPaths = new String[] {
//"part1Hello/Apart2Z/anything/part3_1/any1/any2/part4.extra/"
"part1Hello/Apart2Z/anything/part3_1/any1/part4.extra/"
};
@Rule public TemporaryFolder temp = new TemporaryFolder();
@After
public void tearDown() throws Exception {
}
@Test
public void testConvertNormalizedRelativeRegexToWindows() throws Exception {
final String normalizedRelativeRegex =
"[\\[/]/part1/part2[abc//de/]part3\\\\[123/45\\]67/]part4[\\Q]/[\\E]part5\\Q/[]/\\E";
final String expectedRegex =
"[\\[/]\\\\part1\\\\part2[abc//de/]part3\\\\[123/45\\]67/]part4[\\Q]/[\\E]part5\\Q/[]/\\E";
// make sure patterns are valid!
@SuppressWarnings("unused")
final Pattern normalizedRelativePattern = Pattern.compile(normalizedRelativeRegex);
@SuppressWarnings("unused")
final Pattern expectedPattern = Pattern.compile(expectedRegex);
final String actualRegex = new SimpleHierarchicalMatcher<Path>(true, "", true, true)
.convertNormalizedRelativeRegexToWindows(normalizedRelativeRegex);
assertThat(actualRegex, equalTo(expectedRegex));
}
@Ignore
@Theory(nullsAccepted = false)
public void parentDirsShouldMatchPartially(final @FromDataPoints("globs") String[] globData,
final @FromDataPoints("testPaths") String testString) throws IOException {
final Path testPath = Paths.get(testString);
final Path testDir = testPath.toString().endsWith("/")
? testPath.subpath(0, testPath.getNameCount() - 2)
: testPath;
Files.createDirectories(temp.getRoot().toPath().resolve(testDir));
verifyCondition(globData.length == 2);
final String glob = assertNonNull(globData[0]);
final String noMatchEnd = convertToSystemPath(assertNonNull(globData[1]));
final boolean isUnix = "/".equals(testPath.getFileSystem().getSeparator());
final String regex = isUnix ? Globs.toUnixRegexPattern(glob) : Globs.toWindowsRegexPattern(glob);
final Pattern pattern = Pattern.compile(regex.substring(1, regex.length() - 1));
final Matcher matcher = pattern.matcher(testPath.toString());
assertThat(matcher.matches(), is(false));
for (Path path = testDir; path != null; path = path.getParent()) {
assumeThat(testPath.toString(), startsWith(path.toString()));
matcher.reset(path.toString());
assertThat(matcher.matches(), is(false));
assertThat(matcher.hitEnd(), is(true));
}
final String separator = testDir.getFileSystem().getSeparator();
for (Path path = testDir; path != null; path = path.getParent()) {
assumeThat(testPath.toString(), startsWith(path.toString()));
final String unmatchable = path.toString() + noMatchEnd + separator;
final Matcher submatcher = pattern.matcher(unmatchable);
assertThat(submatcher.matches(), is(false));
assertThat(submatcher.hitEnd(), is(false));
}
}
@SuppressWarnings("null")
private String convertToSystemPath(final String path) {
return Utils.isUnix() ? path : path.replaceAll("/", "\\\\");
}
}