/*
* SonarQube Java
* Copyright (C) 2012-2016 SonarSource SA
* mailto:contact AT sonarsource DOT com
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This program 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
*/
package org.sonar.java.se;
import com.google.common.collect.ImmutableList;
import com.google.common.collect.ImmutableMap;
import org.fest.assertions.Fail;
import org.junit.Test;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import static org.fest.assertions.Assertions.assertThat;
import static org.sonar.java.se.Expectations.IssueAttribute.END_COLUMN;
import static org.sonar.java.se.Expectations.IssueAttribute.END_LINE;
import static org.sonar.java.se.Expectations.IssueAttribute.FLOWS;
import static org.sonar.java.se.Expectations.IssueAttribute.MESSAGE;
import static org.sonar.java.se.Expectations.IssueAttribute.SECONDARY_LOCATIONS;
import static org.sonar.java.se.Expectations.IssueAttribute.START_COLUMN;
public class ExpectationsParserTest {
private static final int LINE = 42;
@Test
public void issue_without_details() {
Map<Expectations.IssueAttribute, Object> issue = Expectations.Parser.parseIssue("// Noncompliant", LINE).issue;
assertThat(issue.get(Expectations.IssueAttribute.LINE)).isEqualTo(LINE);
}
@Test
public void issue_with_message() {
Map<Expectations.IssueAttribute, Object> issue = Expectations.Parser.parseIssue("// Noncompliant {{message}}", LINE).issue;
assertThat(issue.get(MESSAGE)).isEqualTo("message");
}
@Test
public void issue_with_attributes() {
Map<Expectations.IssueAttribute, Object> issue = Expectations.Parser.parseIssue("// Noncompliant [[flows=f1,f2,f3;sc=3;ec=7;el=4;secondary=5]]", LINE).issue;
assertThat(issue.get(FLOWS)).isEqualTo(ImmutableList.of("f1", "f2", "f3"));
assertThat(issue.get(START_COLUMN)).isEqualTo(3);
assertThat(issue.get(END_COLUMN)).isEqualTo(7);
assertThat(issue.get(END_LINE)).isEqualTo(Expectations.Parser.LineRef.fromString("4"));
assertThat(issue.get(SECONDARY_LOCATIONS)).isEqualTo(ImmutableList.of(5));
assertThat(issue.get(MESSAGE)).isNull();
}
@Test
public void relative_end_line_attribute() {
Map<Expectations.IssueAttribute, Object> issue = Expectations.Parser.parseIssue("// Noncompliant [[el=+1]]", LINE).issue;
assertThat(issue.get(END_LINE)).isEqualTo(Expectations.Parser.LineRef.fromString(String.valueOf(LINE + 1)));
}
@Test
public void invalid_attribute_name() {
try {
Expectations.Parser.parseIssue("// Noncompliant [[invalid]]", LINE);
Fail.fail();
} catch (AssertionError e) {
assertThat(e).hasMessage("// Noncompliant attributes not valid: invalid");
}
}
@Test
public void issue_with_attributes_and_comment() {
Map<Expectations.IssueAttribute, Object> issue = Expectations.Parser.parseIssue("// Noncompliant [[sc=1;ec=6]] {{message}}", LINE).issue;
assertThat(issue.get(MESSAGE)).isEqualTo("message");
assertThat(issue.get(START_COLUMN)).isEqualTo(1);
assertThat(issue.get(END_COLUMN)).isEqualTo(6);
}
@Test
public void issue_with_attributes_and_comment_switched() {
Expectations.Issue issue = Expectations.Parser.parseIssue("// Noncompliant {{message}} [[sc=1;ec=6]]", LINE).issue;
assertThat(issue.get(MESSAGE)).isEqualTo("message");
assertThat(issue.get(START_COLUMN)).isEqualTo(1);
assertThat(issue.get(END_COLUMN)).isEqualTo(6);
}
@Test
public void end_line_attribute() {
try {
Expectations.Parser.parseIssue("// Noncompliant [[endLine=-1]] {{message}}", 0);
Fail.fail();
} catch (AssertionError e) {
assertThat(e).hasMessage("endLine attribute should be relative to the line and must be +N with N integer");
}
}
@Test
public void line_shifting() {
Map<Expectations.IssueAttribute, Object> issue = Expectations.Parser.parseIssue("// Noncompliant@-1", LINE).issue;
assertThat(issue.get(Expectations.IssueAttribute.LINE)).isEqualTo(41);
}
@Test
public void no_flows() {
List<Expectations.FlowComment> flows = Expectations.Parser.parseFlows(null, 0);
assertThat(flows).isEmpty();
}
@Test
public void flow_without_details() {
List<Expectations.FlowComment> flows = Expectations.Parser.parseFlows("// flow@npe1", LINE);
assertThat(flows).hasSize(1);
Expectations.FlowComment flow = flows.iterator().next();
assertThat(flow.id).isEqualTo("npe1");
assertThat(flow.line).isEqualTo(LINE);
}
@Test
public void flow_with_message() throws Exception {
List<Expectations.FlowComment> flows = Expectations.Parser.parseFlows("// flow@npe1 {{message}}", LINE);
assertThat(flows).hasSize(1);
Expectations.FlowComment flow = flows.iterator().next();
assertThat(flow.id).isEqualTo("npe1");
assertThat(flow.line).isEqualTo(LINE);
assertThat(flow.attributes.get(MESSAGE)).isEqualTo("message");
}
@Test
public void flow_with_attributes_and_message() throws Exception {
List<Expectations.FlowComment> flows = Expectations.Parser.parseFlows("// flow@npe1 [[sc=1;ec=6]] {{message}}", LINE);
assertThat(flows).hasSize(1);
Expectations.FlowComment flow = flows.iterator().next();
assertThat(flow.id).isEqualTo("npe1");
assertThat(flow.line).isEqualTo(LINE);
assertThat(flow.attributes.get(START_COLUMN)).isEqualTo(1);
assertThat(flow.attributes.get(END_COLUMN)).isEqualTo(6);
assertThat(flow.attributes.get(MESSAGE)).isEqualTo("message");
}
@Test
public void issue_and_flow_on_the_same_line() {
Expectations.Parser.ParsedComment iaf = Expectations.Parser.parseIssue("// Noncompliant [[flows=id]] flow@id", LINE);
assertThat(iaf.issue.get(Expectations.IssueAttribute.LINE)).isEqualTo(LINE);
assertThat((List<?>) iaf.issue.get(FLOWS)).contains("id");
assertThat(iaf.flows).hasSize(1);
Expectations.FlowComment flow = iaf.flows.iterator().next();
assertThat(flow.id).isEqualTo("id");
assertThat(flow.line).isEqualTo(LINE);
}
@Test
public void issue_and_flow_message() {
Expectations.Parser.ParsedComment iaf = Expectations.Parser.parseIssue("// Noncompliant {{issue msg}} flow@id {{flow msg}}", LINE);
assertThat(iaf.issue.get(Expectations.IssueAttribute.MESSAGE)).isEqualTo("issue msg");
assertThat(iaf.flows).hasSize(1);
Expectations.FlowComment flow = iaf.flows.iterator().next();
assertThat(flow.attributes.get(MESSAGE)).isEqualTo("flow msg");
}
@Test
public void issue_and_flow_message2() {
Expectations.Parser.ParsedComment iaf = Expectations.Parser.parseIssue("// Noncompliant flow@id {{flow msg}}", LINE);
assertThat(iaf.issue.get(Expectations.IssueAttribute.MESSAGE)).isNull();
assertThat(iaf.flows).hasSize(1);
Expectations.FlowComment flow = iaf.flows.iterator().next();
assertThat(flow.attributes.get(MESSAGE)).isEqualTo("flow msg");
}
@Test
public void issue_and_flow_attr() {
Expectations.Parser.ParsedComment iaf = Expectations.Parser.parseIssue("// Noncompliant [[sc=1;ec=2]] bla bla flow@id [[sc=3;ec=4]] bla bla", LINE);
assertThat(iaf.issue.get(Expectations.IssueAttribute.START_COLUMN)).isEqualTo(1);
assertThat(iaf.issue.get(Expectations.IssueAttribute.END_COLUMN)).isEqualTo(2);
assertThat(iaf.flows).hasSize(1);
Expectations.FlowComment flow = iaf.flows.iterator().next();
assertThat(flow.attributes.get(START_COLUMN)).isEqualTo(3);
assertThat(flow.attributes.get(END_COLUMN)).isEqualTo(4);
}
@Test
public void issue_and_flow_all_options() {
Expectations.Parser.ParsedComment iaf = Expectations.Parser
.parseIssue("// Noncompliant [[flows;sc=1;ec=2]] bla {{issue msg}} bla flow@id [[sc=3;ec=4]] bla {{flow msg}} bla", LINE);
assertThat(iaf.issue).isEqualTo(ImmutableMap.of(
Expectations.IssueAttribute.LINE, 42,
MESSAGE, "issue msg",
START_COLUMN, 1,
END_COLUMN, 2,
FLOWS, ImmutableList.of()
));
assertThat(iaf.flows).hasSize(1);
Expectations.FlowComment flow = iaf.flows.iterator().next();
assertThat(flow.line).isEqualTo(LINE);
assertThat(flow.attributes).isEqualTo(ImmutableMap.of(
MESSAGE, "flow msg",
START_COLUMN, 3,
END_COLUMN, 4
));
}
@Test
public void issue_and_multiple_flows_on_the_same_line() {
Expectations.Parser.ParsedComment iaf = Expectations.Parser.parseIssue("// Noncompliant [[flows=id]] {{issue msg}} flow@id1,id2 {{flow msg12}} flow@id3 {{flow msg3}}", LINE);
assertThat(iaf.issue.get(Expectations.IssueAttribute.MESSAGE)).isEqualTo("issue msg");
assertThat(iaf.flows).hasSize(3);
List<Integer> lines = iaf.flows.stream().map(f -> f.line).collect(Collectors.toList());
assertThat(lines).isEqualTo(ImmutableList.of(LINE, LINE, LINE));
Map<String, Object> idMsgMap = iaf.flows.stream().collect(Collectors.toMap(f -> f.id, f -> MESSAGE.get(f.attributes)));
assertThat(idMsgMap).isEqualTo(ImmutableMap.of(
"id1", "flow msg12",
"id2", "flow msg12",
"id3", "flow msg3"
));
}
}