| /* |
| * 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; |
| } |
| } |
| } |