Sync bugtraq support for spec v0.3
Change-Id: I2c24d1201d4c36963a708b178e780c1828707269
| | |
| | | [bugtraq "issues"]
|
| | | url = http://code.google.com/p/gitblit/issues/detail?id=%BUGID%
|
| | | logRegex = "[Ii]ssue[-#:\\s]{1}\\d+"
|
| | | logRegex1 = "\\d+"
|
| | | [bugtraq "[pullrequests"]
|
| | | loglinkregex = "[Ii]ssue[-#:\\s]{1}\\d+"
|
| | | logregex = "\\d+"
|
| | | loglinktext = issue-%BUGID%
|
| | | [bugtraq "pullrequests"]
|
| | | url = "https://github.com/gitblit/gitblit/pull/%BUGID%"
|
| | | logRegex = "(?:pull request|pull|pr)\\s*[-#]?([0-9]+)"
|
| | | loglinkregex = "(?:pull request|pull|pr)\\s*[-#]?[0-9]+"
|
| | | logregex = "\\d+"
|
| | | loglinktext = "pull request #%BUGID%"
|
| | |
| | | */ |
| | | package com.syntevo.bugtraq; |
| | | |
| | | import java.io.File; |
| | | import java.io.IOException; |
| | | import java.util.ArrayList; |
| | | import java.util.Collections; |
| | | import java.util.HashSet; |
| | | import java.util.List; |
| | | import java.util.Set; |
| | | import java.io.*; |
| | | import java.util.*; |
| | | |
| | | import org.eclipse.jgit.errors.ConfigInvalidException; |
| | | import org.eclipse.jgit.lib.Config; |
| | | import org.eclipse.jgit.lib.Constants; |
| | | import org.eclipse.jgit.lib.FileMode; |
| | | import org.eclipse.jgit.lib.ObjectId; |
| | | import org.eclipse.jgit.lib.ObjectLoader; |
| | | import org.eclipse.jgit.lib.Repository; |
| | | import org.eclipse.jgit.revwalk.RevCommit; |
| | | import org.eclipse.jgit.revwalk.RevTree; |
| | | import org.eclipse.jgit.revwalk.RevWalk; |
| | | import org.eclipse.jgit.storage.file.FileBasedConfig; |
| | | import org.eclipse.jgit.treewalk.TreeWalk; |
| | | import org.eclipse.jgit.treewalk.filter.PathFilterGroup; |
| | | import org.jetbrains.annotations.NotNull; |
| | | import org.jetbrains.annotations.Nullable; |
| | | import org.eclipse.jgit.errors.*; |
| | | import org.eclipse.jgit.lib.*; |
| | | import org.eclipse.jgit.revwalk.*; |
| | | import org.eclipse.jgit.storage.file.*; |
| | | import org.eclipse.jgit.treewalk.*; |
| | | import org.eclipse.jgit.treewalk.filter.*; |
| | | import org.jetbrains.annotations.*; |
| | | |
| | | public final class BugtraqConfig { |
| | | |
| | | // Constants ============================================================== |
| | | |
| | | private static final String DOT_GIT_BUGTRAQ = ".gitbugtraq"; |
| | | private static final String DOT_TGITCONFIG = ".tgitconfig"; |
| | | |
| | | private static final String BUGTRAQ = "bugtraq"; |
| | | |
| | | private static final String URL = "url"; |
| | | private static final String ENABLED = "enabled"; |
| | | private static final String LOG_REGEX = "logRegex"; |
| | | private static final String LOG_REGEX = "logregex"; |
| | | private static final String LOG_FILTERREGEX = "logfilterregex"; |
| | | private static final String LOG_LINKREGEX = "loglinkregex"; |
| | | private static final String LOG_LINKTEXT = "loglinktext"; |
| | | |
| | | // Static ================================================================= |
| | | |
| | | @Nullable |
| | | public static BugtraqConfig read(@NotNull Repository repository) throws IOException, ConfigInvalidException { |
| | | final Config baseConfig = getBaseConfig(repository); |
| | | Config baseConfig = getBaseConfig(repository, DOT_GIT_BUGTRAQ); |
| | | if (baseConfig == null) { |
| | | baseConfig = getBaseConfig(repository, DOT_TGITCONFIG); |
| | | } |
| | | |
| | | final Set<String> allNames = new HashSet<String>(); |
| | | final Config config = repository.getConfig(); |
| | | if (getString(null, URL, config, baseConfig) != null) { |
| | | allNames.add(null); |
| | | } |
| | | else { |
| | | allNames.addAll(config.getSubsections(BUGTRAQ)); |
| | | if (baseConfig != null) { |
| | | allNames.addAll(baseConfig.getSubsections(BUGTRAQ)); |
| | | } |
| | | } |
| | | |
| | | final List<BugtraqEntry> entries = new ArrayList<BugtraqEntry>(); |
| | | for (String name : allNames) { |
| | | final String url = getString(name, URL, config, baseConfig); |
| | | if (url == null) { |
| | | continue; |
| | | } |
| | | |
| | | final String enabled = getString(name, ENABLED, config, baseConfig); |
| | | if (enabled != null && !"true".equals(enabled)) { |
| | | continue; |
| | | } |
| | | |
| | | final String logIdRegex = getString(name, LOG_REGEX, config, baseConfig); |
| | | if (url == null || logIdRegex == null) { |
| | | String idRegex = getString(name, LOG_REGEX, config, baseConfig); |
| | | if (idRegex == null) { |
| | | return null; |
| | | } |
| | | |
| | | String filterRegex = getString(name, LOG_FILTERREGEX, config, baseConfig); |
| | | final String linkRegex = getString(name, LOG_LINKREGEX, config, baseConfig); |
| | | if (filterRegex == null && linkRegex == null) { |
| | | final String[] split = idRegex.split("\n", Integer.MAX_VALUE); |
| | | if (split.length == 2) { |
| | | // Compatibility with TortoiseGit |
| | | filterRegex = split[0]; |
| | | idRegex = split[1]; |
| | | } |
| | | else { |
| | | // Backwards compatibility with specification version < 0.3 |
| | | final List<String> logIdRegexs = new ArrayList<String>(); |
| | | logIdRegexs.add(logIdRegex); |
| | | |
| | | for (int index = 1; index < Integer.MAX_VALUE; index++) { |
| | | final String logIdRegexN = getString(name, LOG_REGEX + index, config, baseConfig); |
| | | if (logIdRegexN == null) { |
| | |
| | | logIdRegexs.add(logIdRegexN); |
| | | } |
| | | |
| | | entries.add(new BugtraqEntry(url, logIdRegexs)); |
| | | if (logIdRegexs.size() > 1) { |
| | | throw new ConfigInvalidException("More than three " + LOG_REGEX + " entries found. This is not supported anymore since bugtraq version 0.3, use " + LOG_FILTERREGEX + " and " + LOG_LINKREGEX + " instead."); |
| | | } |
| | | else if (logIdRegexs.size() == 1) { |
| | | filterRegex = idRegex; |
| | | idRegex = logIdRegexs.get(0); |
| | | } |
| | | } |
| | | } |
| | | |
| | | final String linkText = getString(name, LOG_LINKTEXT, config, baseConfig); |
| | | entries.add(new BugtraqEntry(url, idRegex, linkRegex, filterRegex, linkText)); |
| | | } |
| | | |
| | | if (entries.isEmpty()) { |
| | |
| | | // Utils ================================================================== |
| | | |
| | | @Nullable |
| | | private static Config getBaseConfig(Repository repository) throws IOException, ConfigInvalidException { |
| | | private static Config getBaseConfig(@NotNull Repository repository, @NotNull String configFileName) throws IOException, ConfigInvalidException { |
| | | final Config baseConfig; |
| | | if (repository.isBare()) { |
| | | // read bugtraq config directly from the repository |
| | | String content = null; |
| | | RevWalk rw = new RevWalk(repository); |
| | | TreeWalk tw = new TreeWalk(repository); |
| | | tw.setFilter(PathFilterGroup.createFromStrings(DOT_GIT_BUGTRAQ)); |
| | | tw.setFilter(PathFilterGroup.createFromStrings(configFileName)); |
| | | try { |
| | | ObjectId headId = repository.getRef(Constants.HEAD).getTarget().getObjectId(); |
| | | RevCommit commit = rw.parseCommit(headId); |
| | |
| | | break; |
| | | } |
| | | } |
| | | } finally { |
| | | } |
| | | finally { |
| | | rw.dispose(); |
| | | tw.release(); |
| | | } |
| | |
| | | } |
| | | else { |
| | | // read bugtraq config from work tree |
| | | final File baseFile = new File(repository.getWorkTree(), DOT_GIT_BUGTRAQ); |
| | | final File baseFile = new File(repository.getWorkTree(), configFileName); |
| | | if (baseFile.isFile()) { |
| | | FileBasedConfig fileConfig = new FileBasedConfig(baseFile, repository.getFS()); |
| | | fileConfig.load(); |
| | |
| | | } |
| | | |
| | | @Nullable |
| | | private static String getString(@NotNull String subsection, @NotNull String key, @NotNull Config config, @Nullable Config baseConfig) { |
| | | private static String getString(@Nullable String subsection, @NotNull String key, @NotNull Config config, @Nullable Config baseConfig) { |
| | | final String value = config.getString(BUGTRAQ, subsection, key); |
| | | if (value != null) { |
| | | return trimMaybeNull(value); |
| | |
| | | */ |
| | | package com.syntevo.bugtraq; |
| | | |
| | | import java.util.*; |
| | | |
| | | import org.jetbrains.annotations.*; |
| | | |
| | | final class BugtraqEntry { |
| | |
| | | // Fields ================================================================= |
| | | |
| | | private final String url; |
| | | private final String logLinkText; |
| | | private final BugtraqParser parser; |
| | | |
| | | // Setup ================================================================== |
| | | |
| | | public BugtraqEntry(@NotNull String url, @NotNull List<String> logIdRegexs) throws BugtraqException { |
| | | public BugtraqEntry(@NotNull String url, @NotNull String logIdRegex, @Nullable String logLinkRegex, @Nullable String logFilterRegex, @Nullable String logLinkText) throws BugtraqException { |
| | | this.url = url; |
| | | this.parser = BugtraqParser.createInstance(logIdRegexs); |
| | | this.logLinkText = logLinkText; |
| | | this.parser = BugtraqParser.createInstance(logIdRegex, logLinkRegex, logFilterRegex); |
| | | } |
| | | |
| | | // Accessing ============================================================== |
| | |
| | | return url; |
| | | } |
| | | |
| | | @Nullable |
| | | public String getLogLinkText() { |
| | | return logLinkText; |
| | | } |
| | | |
| | | @NotNull |
| | | public BugtraqParser getParser() { |
| | | return parser; |
| | |
| | | |
| | | for (BugtraqEntry entry : config.getEntries()) { |
| | | final List<BugtraqParserIssueId> ids = entry.getParser().parse(message); |
| | | if (ids == null) { |
| | | continue; |
| | | } |
| | | |
| | | for (BugtraqParserIssueId id : ids) { |
| | | allIds.add(new IssueId(entry, id)); |
| | | } |
| | |
| | | } |
| | | |
| | | appendText(message.substring(lastIdEnd + 1, id.getFrom()), outputHandler); |
| | | final String logLinkText = issueId.entry.getLogLinkText(); |
| | | final String linkText; |
| | | if (logLinkText != null) { |
| | | linkText = logLinkText.replace("%BUGID%", id.getId()); |
| | | } |
| | | else { |
| | | linkText = message.substring(id.getFrom(), id.getTo() + 1); |
| | | } |
| | | |
| | | final String linkText = message.substring(id.getFrom(), id.getTo() + 1); |
| | | final String target = issueId.entry.getUrl().replace("%BUGID%", id.getId()); |
| | | outputHandler.appendLink(linkText, target); |
| | | lastIdEnd = id.getTo(); |
| | |
| | | // Static ================================================================= |
| | | |
| | | @NotNull |
| | | public static BugtraqParser createInstance(@NotNull List<String> regexs) throws BugtraqException { |
| | | public static BugtraqParser createInstance(@NotNull String idRegex, @Nullable String linkRegex, @Nullable String filterRegex) throws BugtraqException { |
| | | try { |
| | | return new BugtraqParser(regexs); |
| | | return new BugtraqParser(idRegex, linkRegex, filterRegex); |
| | | } |
| | | catch (PatternSyntaxException ex) { |
| | | throw new BugtraqException(ex); |
| | |
| | | |
| | | // Fields ================================================================= |
| | | |
| | | private final List<Pattern> patterns; |
| | | private final Pattern idPattern; |
| | | private final Pattern linkPattern; |
| | | private final Pattern filterPattern; |
| | | |
| | | // Setup ================================================================== |
| | | |
| | | private BugtraqParser(List<String> regexs) { |
| | | this.patterns = new ArrayList<Pattern>(); |
| | | |
| | | for (String regex : regexs) { |
| | | patterns.add(compilePatternSafe(regex)); |
| | | } |
| | | private BugtraqParser(@NotNull String idRegex, @Nullable String linkRegex, @Nullable String filterRegex) { |
| | | idPattern = compilePatternSafe(idRegex); |
| | | linkPattern = linkRegex != null ? compilePatternSafe(linkRegex) : null; |
| | | filterPattern = filterRegex != null ? compilePatternSafe(filterRegex) : null; |
| | | } |
| | | |
| | | // Accessing ============================================================== |
| | |
| | | List<Part> parts = new ArrayList<Part>(); |
| | | parts.add(new Part(message, 0, message.length() - 1)); |
| | | |
| | | boolean firstMatch = false; |
| | | |
| | | for (Pattern pattern : patterns) { |
| | | final List<Part> newParts = new ArrayList<Part>(); |
| | | for (Part part : parts) { |
| | | final Matcher matcher = pattern.matcher(part.text); |
| | | while (matcher.find()) { |
| | | firstMatch = true; |
| | | if (matcher.groupCount() == 0) { |
| | | addNewPart(part, matcher, 0, newParts); |
| | | } |
| | | else { |
| | | addNewPart(part, matcher, 1, newParts); |
| | | } |
| | | } |
| | | if (filterPattern != null) { |
| | | parts = collectParts(parts, filterPattern); |
| | | } |
| | | |
| | | parts = newParts; |
| | | if (parts.isEmpty()) { |
| | | parts = null; |
| | | break; |
| | | } |
| | | } |
| | | |
| | | if (!firstMatch) { |
| | | return null; |
| | | } |
| | | |
| | | if (parts == null) { |
| | | parts = new ArrayList<Part>(); |
| | | if (linkPattern != null) { |
| | | parts = collectParts(parts, linkPattern); |
| | | } |
| | | |
| | | final List<BugtraqParserIssueId> ids = new ArrayList<BugtraqParserIssueId>(); |
| | | for (Part part : parts) { |
| | | final BugtraqParserIssueId id = new BugtraqParserIssueId(part.from, part.to, part.text); |
| | | for (final Part part : parts) { |
| | | final Matcher matcher = idPattern.matcher(part.text); |
| | | while (matcher.find()) { |
| | | final Part subPart = createSubPart(part, matcher, matcher.groupCount() == 0 ? 0 : 1); |
| | | if (subPart == null) { |
| | | continue; |
| | | } |
| | | |
| | | final BugtraqParserIssueId id; |
| | | if (linkPattern == null) { |
| | | id = new BugtraqParserIssueId(subPart.from, subPart.to, subPart.text); |
| | | } |
| | | else { |
| | | if (matcher.find()) { |
| | | // If we are using links, the last pattern (link) must produce exactly one id. |
| | | continue; |
| | | } |
| | | |
| | | id = new BugtraqParserIssueId(part.from, part.to, subPart.text); |
| | | } |
| | | |
| | | if (ids.size() > 0) { |
| | | final BugtraqParserIssueId lastId = ids.get(ids.size() - 1); |
| | | if (id.getFrom() <= lastId.getTo()) { |
| | |
| | | |
| | | ids.add(id); |
| | | } |
| | | } |
| | | |
| | | return ids; |
| | | } |
| | | |
| | | // Utils ================================================================== |
| | | |
| | | private static void addNewPart(Part part, Matcher matcher, int group, List<Part> newParts) { |
| | | private static List<Part> collectParts(@NotNull List<Part> mainParts, @NotNull Pattern pattern) { |
| | | final List<Part> subParts = new ArrayList<Part>(); |
| | | for (final Part part : mainParts) { |
| | | final Matcher matcher = pattern.matcher(part.text); |
| | | while (matcher.find()) { |
| | | final Part newPart = createSubPart(part, matcher, matcher.groupCount() == 0 ? 0 : 1); |
| | | if (newPart != null) { |
| | | subParts.add(newPart); |
| | | } |
| | | } |
| | | } |
| | | |
| | | return subParts; |
| | | } |
| | | |
| | | @Nullable |
| | | private static Part createSubPart(Part part, Matcher matcher, int group) { |
| | | final int textStart = matcher.start(group) + part.from; |
| | | final int textEnd = matcher.end(group) - 1 + part.from; |
| | | if (textEnd < 0) { |
| | | return; |
| | | return null; |
| | | } |
| | | |
| | | final Part newPart = new Part(matcher.group(group), textStart, textEnd); |
| | | newParts.add(newPart); |
| | | return new Part(matcher.group(group), textStart, textEnd); |
| | | } |
| | | |
| | | private static Pattern compilePatternSafe(String pattern) throws PatternSyntaxException { |
| | |
| | | */ |
| | | package com.syntevo.bugtraq; |
| | | |
| | | import junit.framework.*; |
| | | import java.util.ArrayList; |
| | | import java.util.Arrays; |
| | | import java.util.List; |
| | | |
| | | import java.util.*; |
| | | import junit.framework.TestCase; |
| | | |
| | | import org.jetbrains.annotations.*; |
| | | import org.jetbrains.annotations.NotNull; |
| | | import org.jetbrains.annotations.Nullable; |
| | | |
| | | public class BugtraqFormatterTest extends TestCase { |
| | | |
| | | // Accessing ============================================================== |
| | | |
| | | public void testSimple() throws BugtraqException { |
| | | final BugtraqFormatter formatter = createFormatter(createEntry("https://jira.atlassian.com/browse/%BUGID%", "JRA-\\d+")); |
| | | public void testSimpleWithExtendedLink() throws BugtraqException { |
| | | final BugtraqFormatter formatter = createFormatter(createEntry("https://jira.atlassian.com/browse/JRA-%BUGID%", null, "JRA-\\d+", "\\d+", null)); |
| | | doTest(formatter, "JRA-7399: Email subject formatting", l("JRA-7399", "https://jira.atlassian.com/browse/JRA-7399"), t(": Email subject formatting")); |
| | | doTest(formatter, " JRA-7399, JRA-7398: Email subject formatting", t(" "), l("JRA-7399", "https://jira.atlassian.com/browse/JRA-7399"), t(", "), l("JRA-7398", "https://jira.atlassian.com/browse/JRA-7398"), t(": Email subject formatting")); |
| | | doTest(formatter, "Fixed JRA-7399", t("Fixed "), l("JRA-7399", "https://jira.atlassian.com/browse/JRA-7399")); |
| | | } |
| | | |
| | | public void testLinkText() throws BugtraqException { |
| | | final BugtraqFormatter formatter = createFormatter(createEntry("https://jira.atlassian.com/browse/JRA-%BUGID%", null, "JRA-\\d+", "\\d+", "JIRA-%BUGID%")); |
| | | doTest(formatter, " JRA-7399, JRA is text, JRA-7398: Email subject formatting", t(" "), l("JIRA-7399", "https://jira.atlassian.com/browse/JRA-7399"), t(", JRA is text, "), l("JIRA-7398", "https://jira.atlassian.com/browse/JRA-7398"), t(": Email subject formatting")); |
| | | } |
| | | |
| | | public void testTwoNonIntersectingConfigurations() throws BugtraqException { |
| | | final BugtraqFormatter formatter = createFormatter(createEntry("https://jira.atlassian.com/browse/%BUGID%", "JRA-\\d+"), |
| | | createEntry("https://issues.apache.org/jira/browse/%BUGID%", "VELOCITY-\\d+")); |
| | | final BugtraqFormatter formatter = createFormatter(createEntry("https://jira.atlassian.com/browse/%BUGID%", null, null, "JRA-\\d+", null), |
| | | createEntry("https://issues.apache.org/jira/browse/%BUGID%", null, null, "VELOCITY-\\d+", null)); |
| | | doTest(formatter, "JRA-7399, VELOCITY-847: fix", l("JRA-7399", "https://jira.atlassian.com/browse/JRA-7399"), t(", "), l("VELOCITY-847", "https://issues.apache.org/jira/browse/VELOCITY-847"), t(": fix")); |
| | | doTest(formatter, " JRA-7399: fix/VELOCITY-847", t(" "), l("JRA-7399", "https://jira.atlassian.com/browse/JRA-7399"), t(": fix/"), l("VELOCITY-847", "https://issues.apache.org/jira/browse/VELOCITY-847")); |
| | | doTest(formatter, "JRA-7399VELOCITY-847", l("JRA-7399", "https://jira.atlassian.com/browse/JRA-7399"), l("VELOCITY-847", "https://issues.apache.org/jira/browse/VELOCITY-847")); |
| | | } |
| | | |
| | | public void testTwoIntersectingConfigurations() throws BugtraqException { |
| | | final BugtraqFormatter formatter = createFormatter(createEntry("https://host1/%BUGID%", "A[AB]"), |
| | | createEntry("https://host2/%BUGID%", "BA[A]?")); |
| | | final BugtraqFormatter formatter = createFormatter(createEntry("https://host1/%BUGID%", null, null, "A[AB]", null), |
| | | createEntry("https://host2/%BUGID%", null, null, "BA[A]?", null)); |
| | | doTest(formatter, "AA: fix", l("AA", "https://host1/AA"), t(": fix")); |
| | | doTest(formatter, "AB: fix", l("AB", "https://host1/AB"), t(": fix")); |
| | | doTest(formatter, "BA: fix", l("BA", "https://host2/BA"), t(": fix")); |
| | |
| | | return new BugtraqFormatter(new BugtraqConfig(Arrays.asList(entries))); |
| | | } |
| | | |
| | | private BugtraqEntry createEntry(String url, String ... logRegexs) throws BugtraqException { |
| | | return new BugtraqEntry(url, Arrays.asList(logRegexs)); |
| | | private BugtraqEntry createEntry(String url, @Nullable String filterRegex, @Nullable String linkRegex, @NotNull String idRegex, @Nullable String linkText) throws BugtraqException { |
| | | return new BugtraqEntry(url, idRegex, linkRegex, filterRegex, linkText); |
| | | } |
| | | |
| | | private Text t(String text) { |
| | |
| | | |
| | | private void doTest(BugtraqFormatter formatter, String message, Atom ... expectedAtoms) { |
| | | final List<Atom> actualAtoms = new ArrayList<Atom>(); |
| | | final StringBuilder sb = new StringBuilder(); |
| | | formatter.formatLogMessage(message, new BugtraqFormatter.OutputHandler() { |
| | | @Override |
| | | public void appendText(@NotNull String text) { |
| | | actualAtoms.add(t(text)); |
| | | sb.append(text); |
| | | } |
| | | |
| | | @Override |
| | | public void appendLink(@NotNull String name, @NotNull String target) { |
| | | actualAtoms.add(l(name, target)); |
| | | sb.append(name); |
| | | } |
| | | }); |
| | | |
| | |
| | | |
| | | import java.util.*; |
| | | |
| | | import org.jetbrains.annotations.*; |
| | | |
| | | public class BugtraqParserTest extends TestCase { |
| | | |
| | | // Accessing ============================================================== |
| | | |
| | | public void testSimple1() throws BugtraqException { |
| | | final BugtraqParser parser = createParser("\\d"); |
| | | assertNull(parser.parse("")); |
| | | final BugtraqParser parser = createParser(null, null, "\\d+"); |
| | | doTest("", parser); |
| | | doTest("1", parser, id(0, 0, "1")); |
| | | doTest("1 2 3", parser, id(0, 0, "1"), id(2, 2, "2"), id(4, 4, "3")); |
| | | } |
| | | |
| | | public void testSimple2() throws BugtraqException { |
| | | final BugtraqParser parser = createParser("(\\d)"); |
| | | assertNull(parser.parse("")); |
| | | final BugtraqParser parser = createParser(null, null, "(\\d+)"); |
| | | doTest("1", parser, id(0, 0, "1")); |
| | | doTest("1 2 3", parser, id(0, 0, "1"), id(2, 2, "2"), id(4, 4, "3")); |
| | | } |
| | | |
| | | public void testSimple3() throws BugtraqException { |
| | | final BugtraqParser parser = createParser("(SG-\\d)"); |
| | | assertNull(parser.parse("")); |
| | | final BugtraqParser parser = createParser(null, null, "(SG-\\d+)"); |
| | | doTest("SG-1", parser, id(0, 3, "SG-1")); |
| | | doTest("SG-1 SG-2 SG-3", parser, id(0, 3, "SG-1"), id(5, 8, "SG-2"), id(10, 13, "SG-3")); |
| | | } |
| | | |
| | | public void testSimple4() throws BugtraqException { |
| | | final BugtraqParser parser = createParser("SG-(\\d)"); |
| | | assertNull(parser.parse("")); |
| | | final BugtraqParser parser = createParser(null, null, "SG-(\\d+)"); |
| | | doTest("SG-1", parser, id(3, 3, "1")); |
| | | doTest("SG-1 SG-2 SG-3", parser, id(3, 3, "1"), id(8, 8, "2"), id(13, 13, "3")); |
| | | } |
| | | |
| | | public void testTwoLevel1() throws BugtraqException { |
| | | final BugtraqParser parser = createParser("(SG-\\d)", "\\d"); |
| | | public void testFilter1() throws BugtraqException { |
| | | final BugtraqParser parser = createParser("(SG-\\d+)", null, "\\d+"); |
| | | doTest("SG-1", parser, id(3, 3, "1")); |
| | | doTest("SG-1 SG-2 SG-3", parser, id(3, 3, "1"), id(8, 8, "2"), id(13, 13, "3")); |
| | | } |
| | | |
| | | public void testTwoLevel2() throws BugtraqException { |
| | | final BugtraqParser parser = createParser("xSG-\\dx", "\\d"); |
| | | public void testFilter2() throws BugtraqException { |
| | | final BugtraqParser parser = createParser("xSG-\\d+x", null, "\\d+"); |
| | | doTest("SG-1 xSG-2x SG-3", parser, id(9, 9, "2")); |
| | | } |
| | | |
| | | public void testTwoLevel3() throws BugtraqException { |
| | | final BugtraqParser parser = createParser("[Ii]ssues?:?((\\s*(,|and)?\\s*#\\d+)+)", "\\d"); |
| | | public void testFilter3() throws BugtraqException { |
| | | final BugtraqParser parser = createParser("[Ii]ssues?:?((\\s*(,|and)?\\s*#\\d+)+)", null, "\\d+"); |
| | | doTest("Issues #3, #4 and #5: Git Bugtraq Configuration options (see #12)", parser, id(8, 8, "3"), id(12, 12, "4"), id(19, 19, "5")); |
| | | } |
| | | |
| | | public void testThreeLevel() throws BugtraqException { |
| | | public void testLink() throws BugtraqException { |
| | | final BugtraqParser parser = createParser(null, "(SG-\\d+)", "\\d+"); |
| | | doTest("SG-1", parser, id(0, 3, "1")); |
| | | doTest("SG-1 SG-2 SG-3", parser, id(0, 3, "1"), id(5, 8, "2"), id(10, 13, "3")); |
| | | } |
| | | |
| | | public void testLinkAndFilter() throws BugtraqException { |
| | | final BugtraqParser parser = createParser("[ab]\\d[cd]", "a\\dc|b\\dd", "\\d"); |
| | | doTest("a1c a2d b3c b4d", parser, id(1, 1, "1"), id(13, 13, "4")); |
| | | doTest("a1c a2d b3c b4d", parser, id(0, 2, "1"), id(12, 14, "4")); |
| | | } |
| | | |
| | | public void testFogBugz() throws BugtraqException { |
| | | final BugtraqParser parser = createParser("(?:Bug[zs]?\\s*IDs?\\s*|Cases?)[#:; ]+((\\d+[ ,:;#]*)+)", "\\d"); |
| | | doTest("Bug IDs: 3, 4, 5", parser, id(9, 9, "3"), id(12, 12, "4"), id(15, 15, "5")); |
| | | final BugtraqParser parser = createParser("(?:Bug[zs]?\\s*IDs?\\s*|Cases?)[#:; ]+((\\d+[ ,:;#]*)+)", "[#]?\\d+", "\\d+"); |
| | | doTest("Bug IDs: 3, #4, 5", parser, id(9, 9, "3"), id(12, 13, "4"), id(16, 16, "5")); |
| | | } |
| | | |
| | | public void testFogBugzInvalid() throws BugtraqException { |
| | | final BugtraqParser parser = createParser("Bug[zs]?\\s*IDs?\\s*|Cases?[#:; ]+((\\d+[ ,:;#]*)+)", "\\d"); |
| | | final BugtraqParser parser = createParser("Bug[zs]?\\s*IDs?\\s*|Cases?[#:; ]+((\\d+[ ,:;#]*)+)", null, "\\d+"); |
| | | doTest("Bug IDs: 3, 4, 5", parser); |
| | | } |
| | | |
| | | // Utils ================================================================== |
| | | |
| | | private BugtraqParser createParser(String ... regexs) throws BugtraqException { |
| | | return BugtraqParser.createInstance(Arrays.asList(regexs)); |
| | | private BugtraqParser createParser(@Nullable String filterRegex, @Nullable String linkRegex, @NotNull String idRegex) throws BugtraqException { |
| | | return BugtraqParser.createInstance(idRegex, linkRegex, filterRegex); |
| | | } |
| | | |
| | | private BugtraqParserIssueId id(int from, int to, String id) { |