blob: d1e5b95fe7c8e8bd90aa59f0f0b625165768d8ad [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you 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 org.netbeans.junit;
import java.util.LinkedList;
import java.util.List;
/**
* A helper class, which holds informatino about filtered tests
*/
public class Filter {
private IncludeExclude inc[] = new IncludeExclude[] {};
private IncludeExclude exc[] = new IncludeExclude[] {};
/** Creates new Filter */
public Filter() {
}
public void setIncludes(IncludeExclude includes[]) {
inc = arrayCopy(includes);
}
public void setExcludes(IncludeExclude excludes[]) {
exc = arrayCopy(excludes);
}
public IncludeExclude [] getIncludes() {
return arrayCopy(inc);
}
public IncludeExclude [] getExcludes() {
return arrayCopy(exc);
}
public boolean isIncluded(String name) {
int i;
for(i = 0; i < inc.length; i++)
if (inc[i].getName() == null || match(inc[i].getName(), name))
break;
if (0 < inc.length && i == inc.length) {
return false;
}
for(i = 0; i < exc.length; i++)
if (match(exc[i].getName(), name))
break;
return i == exc.length;
}
public String getExpectedFail(String name) {
StringBuffer sb = new StringBuffer();
for (int i = 0; i < inc.length; i++) {
if (inc[i].getName() == null || match(inc[i].getName(), name)) {
if (inc[i].getExpectedFail() != null) {
if (sb.length() != 0)
sb.append("; ");
sb.append(inc[i].getExpectedFail());
}
}
}
if (sb.length() == 0)
return null;
else
return sb.toString();
}
/**
* Matches a string against a pattern. The pattern contains two special
* characters:
* '*' which means zero or more characters,
* '?' which means one and only one character.
*
* This code was stolen from Ant's DirectoryScanner.match(String, String) function.
*
* @param pattern the (non-null) pattern to match against
* @param str the (non-null) string that must be matched against the
* pattern
*
* @return <code>true</code> when the string matches against the pattern,
* <code>false</code> otherwise.
*/
public static boolean match(String pattern, String str) {
if (null == pattern && null == str)
return true;
if (null == pattern || null == str)
return false;
char[] patArr = pattern.toCharArray();
char[] strArr = str.toCharArray();
int patIdxStart = 0;
int patIdxEnd = patArr.length-1;
int strIdxStart = 0;
int strIdxEnd = strArr.length-1;
char ch;
boolean containsStar = false;
for (int i = 0; i < patArr.length; i++) {
if (patArr[i] == '*') {
containsStar = true;
break;
}
}
if (!containsStar) {
// No '*'s, so we make a shortcut
if (patIdxEnd != strIdxEnd) {
return false; // Pattern and string do not have the same size
}
for (int i = 0; i <= patIdxEnd; i++) {
ch = patArr[i];
if (ch != '?' && ch != strArr[i]) {
return false; // Character mismatch
}
}
return true; // String matches against pattern
}
if (patIdxEnd == 0) {
return true; // Pattern contains only '*', which matches anything
}
// Process characters before first star
while((ch = patArr[patIdxStart]) != '*' && strIdxStart <= strIdxEnd) {
if (ch != '?' && ch != strArr[strIdxStart]) {
return false;
}
patIdxStart++;
strIdxStart++;
}
if (strIdxStart > strIdxEnd) {
// All characters in the string are used. Check if only '*'s are
// left in the pattern. If so, we succeeded. Otherwise failure.
for (int i = patIdxStart; i <= patIdxEnd; i++) {
if (patArr[i] != '*') {
return false;
}
}
return true;
}
// Process characters after last star
while((ch = patArr[patIdxEnd]) != '*' && strIdxStart <= strIdxEnd) {
if (ch != '?' && ch != strArr[strIdxEnd]) {
return false;
}
patIdxEnd--;
strIdxEnd--;
}
if (strIdxStart > strIdxEnd) {
// All characters in the string are used. Check if only '*'s are
// left in the pattern. If so, we succeeded. Otherwise failure.
for (int i = patIdxStart; i <= patIdxEnd; i++) {
if (patArr[i] != '*') {
return false;
}
}
return true;
}
// process pattern between stars. padIdxStart and patIdxEnd point
// always to a '*'.
while (patIdxStart != patIdxEnd && strIdxStart <= strIdxEnd) {
int patIdxTmp = -1;
for (int i = patIdxStart+1; i <= patIdxEnd; i++) {
if (patArr[i] == '*') {
patIdxTmp = i;
break;
}
}
if (patIdxTmp == patIdxStart+1) {
// Two stars next to each other, skip the first one.
patIdxStart++;
continue;
}
// Find the pattern between padIdxStart & padIdxTmp in str between
// strIdxStart & strIdxEnd
int patLength = (patIdxTmp-patIdxStart-1);
int strLength = (strIdxEnd-strIdxStart+1);
int foundIdx = -1;
strLoop:
for (int i = 0; i <= strLength - patLength; i++) {
for (int j = 0; j < patLength; j++) {
ch = patArr[patIdxStart+j+1];
if (ch != '?' && ch != strArr[strIdxStart+i+j]) {
continue strLoop;
}
}
foundIdx = strIdxStart+i;
break;
}
if (foundIdx == -1) {
return false;
}
patIdxStart = patIdxTmp;
strIdxStart = foundIdx+patLength;
}
// All characters in the string are used. Check if only '*'s are left
// in the pattern. If so, we succeeded. Otherwise failure.
for (int i = patIdxStart; i <= patIdxEnd; i++) {
if (patArr[i] != '*') {
return false;
}
}
return true;
}
public String toString() {
StringBuffer b = new StringBuffer();
if (0 < inc.length) {
b.append("-i ");
for(int i = 0; i < inc.length; i++) {
b.append(inc[i]);
b.append(' ');
}
}
if (0 < exc.length) {
b.append("-e ");
for(int i = 0; i < exc.length; i++) {
b.append(exc[i]);
b.append(' ');
}
}
return b.toString();
}
private IncludeExclude [] arrayCopy(IncludeExclude [] orig) {
List<IncludeExclude> lst = new LinkedList<IncludeExclude>();
for(int i = 0; i < orig.length; i++)
if (null != orig[i] && !(orig[i].getName() == null && orig[i].getExpectedFail() == null)) {
lst.add(orig[i]);
}
return lst.toArray(new IncludeExclude[0]);
}
public static class IncludeExclude {
private String name;
private String expectedFail;
public IncludeExclude() {
}
public IncludeExclude(String name, String expectedFail) {
this.name = name;
this.expectedFail = expectedFail;
}
public String getName() {
return name;
}
public String getExpectedFail() {
return expectedFail;
}
public void setName(String name) {
this.name = name;
}
public void setExpectedFail(String expectedFail) {
this.expectedFail = expectedFail;
}
public String toString() {
return name+":"+expectedFail;
}
}
}