diff --git a/bots/pr/src/main/java/org/openjdk/skara/bots/pr/PullRequestCheckIssueVisitor.java b/bots/pr/src/main/java/org/openjdk/skara/bots/pr/PullRequestCheckIssueVisitor.java index 5bc400c6c..f84dd79f0 100644 --- a/bots/pr/src/main/java/org/openjdk/skara/bots/pr/PullRequestCheckIssueVisitor.java +++ b/bots/pr/src/main/java/org/openjdk/skara/bots/pr/PullRequestCheckIssueVisitor.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -228,4 +228,11 @@ public void visit(BlacklistIssue issue) { public void visit(BinaryIssue issue) { log.fine("ignored: binary file"); } + + @Override + public void visit(ProblemListsIssue issue) { + failedChecks.add(issue.check().getClass()); + messages.add(issue.issue() + " is used in problem lists: " + issue.files()); + readyForReview = false; + } } diff --git a/cli/src/main/java/org/openjdk/skara/cli/JCheckCLIVisitor.java b/cli/src/main/java/org/openjdk/skara/cli/JCheckCLIVisitor.java index 6bb1a6930..83a167639 100644 --- a/cli/src/main/java/org/openjdk/skara/cli/JCheckCLIVisitor.java +++ b/cli/src/main/java/org/openjdk/skara/cli/JCheckCLIVisitor.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -304,6 +304,14 @@ public void visit(BinaryIssue i) { } } + @Override + public void visit(ProblemListsIssue i) { + if (!ignore.contains(i.check().name())) { + println(i, i.issue() + " is used in problem lists " + i.files()); + hasDisplayedErrors = true; + } + } + public boolean hasDisplayedErrors() { return hasDisplayedErrors; } diff --git a/jcheck/src/main/java/org/openjdk/skara/jcheck/ChecksConfiguration.java b/jcheck/src/main/java/org/openjdk/skara/jcheck/ChecksConfiguration.java index fcbe4ffaf..f96745be3 100644 --- a/jcheck/src/main/java/org/openjdk/skara/jcheck/ChecksConfiguration.java +++ b/jcheck/src/main/java/org/openjdk/skara/jcheck/ChecksConfiguration.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -25,7 +25,6 @@ import org.openjdk.skara.ini.Section; import java.util.List; -import java.util.Set; import java.util.stream.Collectors; public class ChecksConfiguration { @@ -36,7 +35,8 @@ public class ChecksConfiguration { ReviewersConfiguration.DEFAULT, MergeConfiguration.DEFAULT, CommitterConfiguration.DEFAULT, - IssuesConfiguration.DEFAULT); + IssuesConfiguration.DEFAULT, + ProblemListsConfiguration.DEFAULT); private final List error; private final List warning; @@ -45,6 +45,7 @@ public class ChecksConfiguration { private final MergeConfiguration merge; private final CommitterConfiguration committer; private final IssuesConfiguration issues; + private final ProblemListsConfiguration problemlists; ChecksConfiguration(List error, List warning, @@ -52,7 +53,8 @@ public class ChecksConfiguration { ReviewersConfiguration reviewers, MergeConfiguration merge, CommitterConfiguration committer, - IssuesConfiguration issues) { + IssuesConfiguration issues, + ProblemListsConfiguration problemlists) { this.error = error; this.warning = warning; this.whitespace = whitespace; @@ -60,6 +62,7 @@ public class ChecksConfiguration { this.merge = merge; this.committer = committer; this.issues = issues; + this.problemlists = problemlists; } public List error() { @@ -108,6 +111,10 @@ public IssuesConfiguration issues() { return issues; } + public ProblemListsConfiguration problemlists() { + return problemlists; + } + static String name() { return "checks"; } @@ -125,7 +132,7 @@ static ChecksConfiguration parse(Section s) { var merge = MergeConfiguration.parse(s.subsection(MergeConfiguration.name())); var committer = CommitterConfiguration.parse(s.subsection(CommitterConfiguration.name())); var issues = IssuesConfiguration.parse(s.subsection(IssuesConfiguration.name())); - - return new ChecksConfiguration(error, warning, whitespace, reviewers, merge, committer, issues); + var problemlists = ProblemListsConfiguration.parse(s.subsection(ProblemListsConfiguration.name())); + return new ChecksConfiguration(error, warning, whitespace, reviewers, merge, committer, issues, problemlists); } } diff --git a/jcheck/src/main/java/org/openjdk/skara/jcheck/IssueVisitor.java b/jcheck/src/main/java/org/openjdk/skara/jcheck/IssueVisitor.java index 3bd2a5603..7894824e1 100644 --- a/jcheck/src/main/java/org/openjdk/skara/jcheck/IssueVisitor.java +++ b/jcheck/src/main/java/org/openjdk/skara/jcheck/IssueVisitor.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -44,4 +44,5 @@ public interface IssueVisitor { void visit(BlacklistIssue issue); void visit(BinaryIssue issue); void visit(SymlinkIssue issue); + void visit(ProblemListsIssue problemListIssue); } diff --git a/jcheck/src/main/java/org/openjdk/skara/jcheck/JCheck.java b/jcheck/src/main/java/org/openjdk/skara/jcheck/JCheck.java index 269a6cb93..6c0732414 100644 --- a/jcheck/src/main/java/org/openjdk/skara/jcheck/JCheck.java +++ b/jcheck/src/main/java/org/openjdk/skara/jcheck/JCheck.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2018, 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2018, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -78,6 +78,7 @@ public class JCheck { new IssuesCheck(utils), new ExecutableCheck(), new SymlinkCheck(), + new ProblemListsCheck(repository), new BlacklistCheck(blacklist) ); repositoryChecks = List.of( diff --git a/jcheck/src/main/java/org/openjdk/skara/jcheck/ProblemListsCheck.java b/jcheck/src/main/java/org/openjdk/skara/jcheck/ProblemListsCheck.java new file mode 100644 index 000000000..f8c40d650 --- /dev/null +++ b/jcheck/src/main/java/org/openjdk/skara/jcheck/ProblemListsCheck.java @@ -0,0 +1,110 @@ +/* + * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package org.openjdk.skara.jcheck; + +import org.openjdk.skara.vcs.Commit; +import org.openjdk.skara.vcs.FileEntry; +import org.openjdk.skara.vcs.Hash; +import org.openjdk.skara.vcs.ReadOnlyRepository; +import org.openjdk.skara.vcs.openjdk.CommitMessage; + +import java.io.IOException; +import java.io.UncheckedIOException; +import java.nio.file.Path; +import java.util.*; +import java.util.logging.Logger; +import java.util.regex.Pattern; +import java.util.stream.Stream; + +public class ProblemListsCheck extends CommitCheck { + private final Logger log = Logger.getLogger("org.openjdk.skara.jcheck.problemlists"); + private static final Pattern WHITESPACES = Pattern.compile("\\s+"); + + private final ReadOnlyRepository repo; + + ProblemListsCheck(ReadOnlyRepository repo) { + this.repo = repo; + } + + private Stream getProblemListedIssues(Path path, Hash hash){ + try { + var lines = repo.lines(path, hash); + if (lines.isEmpty()) { + return Stream.empty(); + } + return lines.get() + .stream() + .map(String::trim) + .filter(s -> !s.startsWith("#")) + .map(WHITESPACES::split) + .filter(ss -> ss.length > 1) + .map(ss -> ss[1]) + .flatMap(s -> Arrays.stream(s.split(","))); + } catch (IOException e) { + throw new UncheckedIOException(e); + } + } + + @Override + Iterator check(Commit commit, CommitMessage message, JCheckConfiguration conf) { + var problemListed = new HashMap>(); + var checkConf = conf.checks().problemlists(); + var dirs = checkConf.dirs(); + var pattern = Pattern.compile(checkConf.pattern()).asMatchPredicate(); + try { + var hash = commit.hash(); + for (var dir : dirs.split("\\|")) { + repo.files(hash, Path.of(dir)) + .stream() + .map(FileEntry::path) + .filter(p -> pattern.test(p.getFileName().toString())) + .forEach(p -> getProblemListedIssues(p, commit.hash()).forEach(t -> problemListed.compute(t, + (k, v) -> {if (v == null) v = new ArrayList<>(); v.add(p); return v;}))); + } + } catch (IOException e) { + throw new UncheckedIOException(e); + } + + var metadata = CommitIssue.metadata(commit, message, conf, this); + var issues = new ArrayList(); + for (var issue : message.issues()) { + var problemLists = problemListed.get(issue.id()); + if (problemLists != null) { + log.finer(String.format("issue: %s is found in problem lists: %s", issue.id(), problemLists)); + issues.add(new ProblemListsIssue(metadata, issue.id(), new HashSet<>(problemLists))); + } + } + + return issues.iterator(); + } + + @Override + public String name() { + return "problemlists"; + } + + @Override + public String description() { + return "Fixed issue should not be in a problem list"; + } +} diff --git a/jcheck/src/main/java/org/openjdk/skara/jcheck/ProblemListsConfiguration.java b/jcheck/src/main/java/org/openjdk/skara/jcheck/ProblemListsConfiguration.java new file mode 100644 index 000000000..02d103386 --- /dev/null +++ b/jcheck/src/main/java/org/openjdk/skara/jcheck/ProblemListsConfiguration.java @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package org.openjdk.skara.jcheck; + +import org.openjdk.skara.ini.Section; + +public class ProblemListsConfiguration { + static final ProblemListsConfiguration DEFAULT = + new ProblemListsConfiguration("test", "^ProblemList.*.txt$"); + + private final String dirs; + private final String pattern; + + ProblemListsConfiguration(String dirs, String patterns) { + this.dirs = dirs; + this.pattern = patterns; + } + + public String dirs() { + return dirs; + } + + public String pattern() { + return pattern; + } + + static String name() { + return "problemlists"; + } + + static ProblemListsConfiguration parse(Section s) { + if (s == null) { + return DEFAULT; + } + + var dirs = s.get("dirs", DEFAULT.dirs()); + var pattern = s.get("pattern", DEFAULT.pattern()); + return new ProblemListsConfiguration(dirs, pattern); + } +} diff --git a/jcheck/src/main/java/org/openjdk/skara/jcheck/ProblemListsIssue.java b/jcheck/src/main/java/org/openjdk/skara/jcheck/ProblemListsIssue.java new file mode 100644 index 000000000..6292b6181 --- /dev/null +++ b/jcheck/src/main/java/org/openjdk/skara/jcheck/ProblemListsIssue.java @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package org.openjdk.skara.jcheck; + +import java.nio.file.Path; +import java.util.Set; + +public class ProblemListsIssue extends CommitIssue { + private final String issue; + private final Set files; + + ProblemListsIssue(CommitIssue.Metadata metadata, String issue, Set files) { + super(metadata); + this.issue = issue; + this.files = files; + } + + @Override + public void accept(IssueVisitor v) { + v.visit(this); + } + + public String issue() { + return issue; + } + + public Set files() { + return files; + } +} + diff --git a/jcheck/src/test/java/org/openjdk/skara/jcheck/JCheckTests.java b/jcheck/src/test/java/org/openjdk/skara/jcheck/JCheckTests.java index 07b88d272..fa4af814c 100644 --- a/jcheck/src/test/java/org/openjdk/skara/jcheck/JCheckTests.java +++ b/jcheck/src/test/java/org/openjdk/skara/jcheck/JCheckTests.java @@ -1,5 +1,5 @@ /* - * Copyright (c) 2019, Oracle and/or its affiliates. All rights reserved. + * Copyright (c) 2019, 2020, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it @@ -237,6 +237,11 @@ public void visit(BinaryIssue e) { issues.add(e); } + @Override + public void visit(ProblemListsIssue e) { + issues.add(e); + } + Set issues() { return issues; } diff --git a/jcheck/src/test/java/org/openjdk/skara/jcheck/ProblemListsCheckTests.java b/jcheck/src/test/java/org/openjdk/skara/jcheck/ProblemListsCheckTests.java new file mode 100644 index 000000000..53b326f7b --- /dev/null +++ b/jcheck/src/test/java/org/openjdk/skara/jcheck/ProblemListsCheckTests.java @@ -0,0 +1,399 @@ +/* + * Copyright (c) 2020, Oracle and/or its affiliates. All rights reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA + * or visit www.oracle.com if you need additional information or have any + * questions. + */ +package org.openjdk.skara.jcheck; + +import org.junit.jupiter.api.Test; +import org.openjdk.skara.vcs.*; +import org.openjdk.skara.vcs.openjdk.CommitMessage; +import org.openjdk.skara.vcs.openjdk.CommitMessageParsers; + +import java.io.IOException; +import java.nio.file.Path; +import java.time.ZonedDateTime; +import java.util.*; + +import static org.junit.jupiter.api.Assertions.assertEquals; +import static org.junit.jupiter.api.Assertions.assertTrue; + +class ProblemListsCheckTests { + + // Default dirs and pattern + private static final List CONFIGURATION = List.of( + "[general]", + "project = test", + "[checks]", + "error = problemlists" + ); + + // Default dirs and custom pattern + private static final List CONFIGURATION2 = List.of( + "[general]", + "project = test", + "[checks]", + "error = problemlists", + "[checks \"problemlists\"]", + "pattern = ^ProjProblemList.txt$" + ); + + // custom dirs and default pattern + private static final List CONFIGURATION3 = List.of( + "[general]", + "project = test", + "[checks]", + "error = problemlists", + "[checks \"problemlists\"]", + "dirs = test1|test2" + ); + + // custom dirs and custom pattern + private static final List CONFIGURATION4 = List.of( + "[general]", + "project = test", + "[checks]", + "error = problemlists", + "[checks \"problemlists\"]", + "dirs = test1|test2", + "pattern = ^ProjProblemList.txt$" + ); + + private static final JCheckConfiguration conf = JCheckConfiguration.parse(CONFIGURATION); + private static final JCheckConfiguration conf2 = JCheckConfiguration.parse(CONFIGURATION2); + private static final JCheckConfiguration conf3 = JCheckConfiguration.parse(CONFIGURATION3); + private static final JCheckConfiguration conf4 = JCheckConfiguration.parse(CONFIGURATION4); + + private static final ReadOnlyRepository REPOSITORY = new TestRepository() { + @Override + // always has test*/ProblemList.txt and test*/ProjProblemList.txt + // for h == 1XXXX has test*/ProblemList1.txt + // for h == 2XXXX has test*/ProblemList2.txt + public List files(Hash h, List paths) throws IOException { + List result = new ArrayList<>(); + for (var path : paths) { + if (path.equals(Path.of("test"))) { + result.addAll(filesAt("test", h)); + } else if (path.equals(Path.of("test1"))) { + result.addAll(filesAt("test1", h)); + } else if (path.equals(Path.of("test2"))) { + result.addAll(filesAt("test2", h)); + } else { + result.addAll(super.files(h, paths)); + } + } + return result; + } + + private List filesAt(String dir, Hash h) { + var fileType = FileType.fromOctal("100644"); + switch (h.hex().charAt(0)) { + case '1': + return List.of(new FileEntry(h, fileType, h, Path.of(dir + "/ProblemList.txt")), + new FileEntry(h, fileType, h, Path.of(dir + "/ProblemList1.txt")), + new FileEntry(h, fileType, h, Path.of(dir + "/ProjProblemList.txt"))); + case '2': + return List.of(new FileEntry(h, fileType, h, Path.of(dir + "/ProblemList.txt")), + new FileEntry(h, fileType, h, Path.of(dir + "/ProblemList2.txt")), + new FileEntry(h, fileType, h, Path.of(dir + "/ProjProblemList.txt"))); + default: + return List.of(new FileEntry(h, fileType, h, Path.of(dir + "/ProblemList.txt")), + new FileEntry(h, fileType, h, Path.of(dir + "/ProjProblemList.txt"))); + } + } + + @Override + // ProblemList*.txt always contain tests problem listed because of bugs 2 and 3 and unless h[0] == 1 b/c of 1 + // ProjProblemList.txt always contain tests problem listed because of PROJ-2,PROJ-3 and PROJ1-1 + // and unless h[0] == 1 b/c of PROJ-1 + public Optional> lines(Path p, Hash h) throws IOException { + if (p.getParent().toString().startsWith("test")) { + List result; + var filename = p.getFileName().toString(); + if (filename.startsWith("ProblemList") && filename.endsWith(".txt")) { + if (h.hex().charAt(0) == '1') { + result = List.of("test1 2", "test3 2,3", "# test 1,2,3"); + } else { + result = List.of("test1 1", "test1 2", "test3 2,3", "# test 1,2,3"); + } + } else if (filename.equals("ProjProblemList.txt")) { + if (h.hex().charAt(0) == '1') { + result = List.of("test1 PROJ-2", "test3 PROJ-2,PROJ-3,PROJ1-1", "# test PROJ-1,PROJ-2,PROJ-3"); + } else { + result = List.of("test1 PROJ-1", "test1 PROJ-2", "test3 PROJ-2,PROJ-3,PROJ1-1", "# test PROJ-1,PROJ-2,PROJ-3"); + } + } else { + return super.lines(p, h); + } + return Optional.of(result); + } + return super.lines(p, h); + } + }; + + private static Commit commit(int id, String... message) { + var author = new Author("foo", "foo@host.org"); + var hash = new Hash(("" + id).repeat(40)); + var parents = List.of(Hash.zero()); + var date = ZonedDateTime.now(); + var metadata = new CommitMetadata(hash, parents, author, author, date, List.of(message)); + return new Commit(metadata, List.of()); + } + + private static CommitMessage message(Commit c) { + return CommitMessageParsers.v1.parse(c); + } + + private List toList(Iterator i) { + var list = new ArrayList(); + while (i.hasNext()) { + list.add(i.next()); + } + return list; + } + + @Test + void titleOnlyMessageShouldBypass() { + var commit = commit(0, "Bugfix"); + var message = message(commit); + var check = new ProblemListsCheck(REPOSITORY); + var issues = toList(check.check(commit, message, conf)); + + assertEquals(0, issues.size()); + } + + @Test + void singleNeverBeenProblemListed() { + var commit = commit(0, "4: Bugfix"); + var message = message(commit); + var check = new ProblemListsCheck(REPOSITORY); + var issues = toList(check.check(commit, message, conf)); + + assertEquals(0, issues.size()); + } + + @Test + void singlePrefixedNeverBeenProblemListed() { + var commit = commit(0, "PROJ-1: Bugfix"); + var message = message(commit); + var check = new ProblemListsCheck(REPOSITORY); + var issues = toList(check.check(commit, message, conf)); + + assertEquals(0, issues.size()); + } + + @Test + void multipleHaveNeverBeenProblemListed() { + var commit = commit(0, "4: Bugfix", "5: Bugfix2"); + var message = message(commit); + var check = new ProblemListsCheck(REPOSITORY); + var issues = toList(check.check(commit, message, conf)); + + assertEquals(0, issues.size()); + } + + @Test + void singleAlwaysProblemListed() { + var commit = commit(0, "3: Bugfix"); + var message = message(commit); + var check = new ProblemListsCheck(REPOSITORY); + var issues = toList(check.check(commit, message, conf)); + + assertEquals(1, issues.size()); + assertTrue(issues.get(0) instanceof ProblemListsIssue); + var issue = (ProblemListsIssue) issues.get(0); + assertEquals("3", issue.issue()); + assertEquals(Set.of(Path.of("test/ProblemList.txt")), issue.files()); + } + + @Test + void singleUnproblemListed() { + var commit = commit(1, "1: Bugfix"); + var message = message(commit); + var check = new ProblemListsCheck(REPOSITORY); + var issues = toList(check.check(commit, message, conf)); + + assertEquals(0, issues.size()); + } + + @Test + void singleAlwaysProblemListedInTwoLists() { + var check = new ProblemListsCheck(REPOSITORY); + + { + var commit = commit(1, "2: Bugfix"); + var message = message(commit); + var issues = toList(check.check(commit, message, conf)); + + assertEquals(1, issues.size()); + assertTrue(issues.get(0) instanceof ProblemListsIssue); + var issue = (ProblemListsIssue) issues.get(0); + assertEquals("2", issue.issue()); + assertEquals(Set.of(Path.of("test/ProblemList.txt"), + Path.of("test/ProblemList1.txt")), issue.files()); + } + + { + var commit = commit(2, "2: Bugfix"); + var message = message(commit); + var issues = toList(check.check(commit, message, conf)); + + assertEquals(1, issues.size()); + assertTrue(issues.get(0) instanceof ProblemListsIssue); + var issue = (ProblemListsIssue) issues.get(0); + assertEquals("2", issue.issue()); + assertEquals(Set.of(Path.of("test/ProblemList.txt"), + Path.of("test/ProblemList2.txt")), issue.files()); + } + } + + @Test + void multipleAlwaysProblemListed() { + var commit = commit(0, "2: Bugfix", "3: Bugfix2"); + var message = message(commit); + var check = new ProblemListsCheck(REPOSITORY); + var issues = toList(check.check(commit, message, conf)); + + assertEquals(2, issues.size()); + // assume that issues are in the same order as messages + assertTrue(issues.get(0) instanceof ProblemListsIssue); + var issue = (ProblemListsIssue) issues.get(0); + assertEquals("2", issue.issue()); + assertEquals(Set.of(Path.of("test/ProblemList.txt")), issue.files()); + + issue = (ProblemListsIssue) issues.get(1); + assertEquals("3", issue.issue()); + assertEquals(Set.of(Path.of("test/ProblemList.txt")), issue.files()); + } + + @Test + void multipleYetOnlyOneProblemListed() { + var commit = commit(0, "4: Bugfix", "3: Bugfix2"); + var message = message(commit); + var check = new ProblemListsCheck(REPOSITORY); + var issues = toList(check.check(commit, message, conf)); + + assertEquals(1, issues.size()); + // assume that issues are in the same order as messages + assertTrue(issues.get(0) instanceof ProblemListsIssue); + var issue = (ProblemListsIssue) issues.get(0); + assertEquals("3", issue.issue()); + assertEquals(Set.of(Path.of("test/ProblemList.txt")), issue.files()); + } + + @Test + void singlePrefixedNeverBeenProblemListedConf2() { + var commit = commit(0, "PROJ-4: Bugfix"); + var message = message(commit); + var check = new ProblemListsCheck(REPOSITORY); + var issues = toList(check.check(commit, message, conf2)); + + assertEquals(0, issues.size()); + } + + @Test + void singleNeverBeenProblemListedConf2() { + var commit = commit(0, "1: Bugfix"); + var message = message(commit); + var check = new ProblemListsCheck(REPOSITORY); + var issues = toList(check.check(commit, message, conf2)); + + assertEquals(0, issues.size()); + } + + @Test + void singlePrefixedAlwaysProblemListedConf2() { + var commit = commit(0, "PROJ-3: Bugfix"); + var message = message(commit); + var check = new ProblemListsCheck(REPOSITORY); + var issues = toList(check.check(commit, message, conf2)); + + assertEquals(1, issues.size()); + assertTrue(issues.get(0) instanceof ProblemListsIssue); + var issue = (ProblemListsIssue) issues.get(0); + assertEquals("PROJ-3", issue.issue()); + assertEquals(Set.of(Path.of("test/ProjProblemList.txt")), issue.files()); + } + + @Test + void singlePrefixedUnproblemListedConf2() { + var commit = commit(1, "PROJ-1: Bugfix"); + var message = message(commit); + var check = new ProblemListsCheck(REPOSITORY); + var issues = toList(check.check(commit, message, conf2)); + + assertEquals(0, issues.size()); + } + + @Test + void singleAlwaysProblemListedInTwoListsConf3() { + var check = new ProblemListsCheck(REPOSITORY); + + { + var commit = commit(1, "2: Bugfix"); + var message = message(commit); + var issues = toList(check.check(commit, message, conf3)); + + assertEquals(1, issues.size()); + assertTrue(issues.get(0) instanceof ProblemListsIssue); + var issue = (ProblemListsIssue) issues.get(0); + assertEquals("2", issue.issue()); + assertEquals(Set.of( + Path.of("test1/ProblemList.txt"), + Path.of("test1/ProblemList1.txt"), + Path.of("test2/ProblemList.txt"), + Path.of("test2/ProblemList1.txt")), issue.files()); + } + + { + var commit = commit(2, "2: Bugfix"); + var message = message(commit); + var issues = toList(check.check(commit, message, conf3)); + + assertEquals(1, issues.size()); + assertTrue(issues.get(0) instanceof ProblemListsIssue); + var issue = (ProblemListsIssue) issues.get(0); + assertEquals("2", issue.issue()); + assertEquals(Set.of( + Path.of("test1/ProblemList.txt"), + Path.of("test1/ProblemList2.txt"), + Path.of("test2/ProblemList.txt"), + Path.of("test2/ProblemList2.txt")), issue.files()); + } + } + + @Test + void singlePrefixedAlwaysProblemListedConf4() { + var check = new ProblemListsCheck(REPOSITORY); + + var commit = commit(0, "PROJ-2: Bugfix"); + var message = message(commit); + var issues = toList(check.check(commit, message, conf4)); + + assertEquals(1, issues.size()); + assertTrue(issues.get(0) instanceof ProblemListsIssue); + var issue = (ProblemListsIssue) issues.get(0); + assertEquals("PROJ-2", issue.issue()); + assertEquals(Set.of(Path.of("test1/ProjProblemList.txt"), + Path.of("test2/ProjProblemList.txt")), issue.files()); + + } + +} \ No newline at end of file