From 7dbe8ce56ffbce55e55e7c2ecce694e82c71bc91 Mon Sep 17 00:00:00 2001 From: Thomas Pohl Date: Mon, 23 Mar 2020 07:48:29 +0100 Subject: [PATCH] Tests + sonar findings --- .../checks/verifier/CheckMessageTest.java | 36 +++++ .../verifier/CheckMessagesVerifierTest.java | 140 ++++++++++++++++++ .../sonar/esql/codecoverage/TraceParser.java | 17 ++- 3 files changed, 188 insertions(+), 5 deletions(-) create mode 100644 esql-checks-test/src/test/java/com/exxeta/iss/sonar/esql/checks/verifier/CheckMessageTest.java create mode 100644 esql-checks-test/src/test/java/com/exxeta/iss/sonar/esql/checks/verifier/CheckMessagesVerifierTest.java diff --git a/esql-checks-test/src/test/java/com/exxeta/iss/sonar/esql/checks/verifier/CheckMessageTest.java b/esql-checks-test/src/test/java/com/exxeta/iss/sonar/esql/checks/verifier/CheckMessageTest.java new file mode 100644 index 00000000..3656571a --- /dev/null +++ b/esql-checks-test/src/test/java/com/exxeta/iss/sonar/esql/checks/verifier/CheckMessageTest.java @@ -0,0 +1,36 @@ +/* + * Sonar ESQL Plugin + * Copyright (C) 2013-2020 Thomas Pohl and EXXETA AG + * http://www.exxeta.com + * + * Licensed 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 com.exxeta.iss.sonar.esql.checks.verifier; + +import org.junit.Test; +import static org.assertj.core.api.Assertions.assertThat; + +public class CheckMessageTest { + @Test + public void testFormatDefaultMessage() { + CheckMessage message = new CheckMessage(null, "Value is {0,number,integer}, expected value is {1,number,integer}.", 3, 7); + assertThat(message.formatDefaultMessage()).isEqualTo("Value is 3, expected value is 7."); + } + @Test + public void testNotFormatMessageWithoutParameters() { + CheckMessage message = new CheckMessage(null, "public void main(){."); // This message can't be used as a pattern by the MessageFormat + // class + assertThat(message.formatDefaultMessage()).isEqualTo("public void main(){."); + } +} diff --git a/esql-checks-test/src/test/java/com/exxeta/iss/sonar/esql/checks/verifier/CheckMessagesVerifierTest.java b/esql-checks-test/src/test/java/com/exxeta/iss/sonar/esql/checks/verifier/CheckMessagesVerifierTest.java new file mode 100644 index 00000000..8be1db7b --- /dev/null +++ b/esql-checks-test/src/test/java/com/exxeta/iss/sonar/esql/checks/verifier/CheckMessagesVerifierTest.java @@ -0,0 +1,140 @@ +/* + * Sonar ESQL Plugin + * Copyright (C) 2013-2020 Thomas Pohl and EXXETA AG + * http://www.exxeta.com + * + * Licensed 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 com.exxeta.iss.sonar.esql.checks.verifier; + +import org.junit.Rule; +import org.junit.Test; +import org.junit.rules.ExpectedException; + +import java.util.Arrays; +import java.util.Collection; +import java.util.Collections; + +import static org.hamcrest.core.StringContains.containsString; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + + +public class CheckMessagesVerifierTest { + @Rule + public ExpectedException thrown = ExpectedException.none(); + + @Test + public void next() { + thrown.expect(AssertionError.class); + thrown.expectMessage("\nExpected violation"); + CheckMessagesVerifier.verify(Collections.EMPTY_LIST) + .next(); + } + + @Test + public void noMore() { + thrown.expect(AssertionError.class); + thrown.expectMessage("\nNo more violations expected\ngot: at line 1"); + Collection messages = Arrays.asList(mockCheckMessage(1, "foo")); + CheckMessagesVerifier.verify(messages) + .noMore(); + } + + @Test + public void line() { + thrown.expect(AssertionError.class); + thrown.expectMessage("\nExpected: 2\ngot: 1"); + Collection messages = Arrays.asList(mockCheckMessage(1, "foo")); + CheckMessagesVerifier.verify(messages) + .next().atLine(2); + } + + @Test + public void line_withoutHasNext() { + thrown.expect(IllegalStateException.class); + thrown.expectMessage("Prior to this method you should call next()"); + Collection messages = Arrays.asList(mockCheckMessage(1, "foo")); + CheckMessagesVerifier.verify(messages) + .atLine(2); + } + + @Test + public void withMessage() { + thrown.expect(AssertionError.class); + thrown.expectMessage(containsString("Expected: \"bar\"")); + thrown.expectMessage(containsString("got: \"foo\"")); + Collection messages = Arrays.asList(mockCheckMessage(1, "foo")); + CheckMessagesVerifier.verify(messages) + .next().atLine(1).withMessage("bar"); + } + + @Test + public void withMessage_withoutHasNext() { + thrown.expect(IllegalStateException.class); + thrown.expectMessage("Prior to this method you should call next()"); + Collection messages = Arrays.asList(mockCheckMessage(1, "foo")); + CheckMessagesVerifier.verify(messages) + .withMessage("foo"); + } + + @Test + public void withMessageThat() { + thrown.expect(AssertionError.class); + thrown.expectMessage("\nExpected: a string containing \"bar\"\n but: was \"foo\""); + Collection messages = Arrays.asList(mockCheckMessage(1, "foo")); + CheckMessagesVerifier.verify(messages) + .next().atLine(1).withMessageThat(containsString("bar")); + } + + @Test + public void withCost() { + thrown.expect(AssertionError.class); + thrown.expectMessage(containsString("Expected: 1.0")); + thrown.expectMessage(containsString("got: 0.0")); + Collection messages = Arrays.asList(mockCheckMessage(1, "foo", 0d)); + CheckMessagesVerifier.verify(messages) + .next().withCost(1d); + } + + @Test + public void ok() { + Collection messages = Arrays.asList( + mockCheckMessage(null, "b"), + mockCheckMessage(2, "a", 1d), + mockCheckMessage(null, "a"), + mockCheckMessage(1, "b"), + mockCheckMessage(1, "a")); + CheckMessagesVerifier.verify(messages) + .next().atLine(null).withMessage("a") + .next().atLine(null).withMessageThat(containsString("b")) + .next().atLine(1).withMessage("a") + .next().atLine(1).withMessage("b") + .next().atLine(2).withMessage("a").withCost(1d) + .noMore(); + } + + private static final CheckMessage mockCheckMessage(Integer line, String message, Double cost) { + CheckMessage checkMessage = mock(CheckMessage.class); + when(checkMessage.getLine()).thenReturn(line); + when(checkMessage.getDefaultMessage()).thenReturn(message); + when(checkMessage.getText()).thenReturn(message); + when(checkMessage.getCost()).thenReturn(cost); + return checkMessage; + } + + private static final CheckMessage mockCheckMessage(Integer line, String message) { + return mockCheckMessage(line, message, null); + } +} diff --git a/esql-code-coverage/src/main/java/com/exxeta/iss/sonar/esql/codecoverage/TraceParser.java b/esql-code-coverage/src/main/java/com/exxeta/iss/sonar/esql/codecoverage/TraceParser.java index 2be90a47..02bb03f4 100644 --- a/esql-code-coverage/src/main/java/com/exxeta/iss/sonar/esql/codecoverage/TraceParser.java +++ b/esql-code-coverage/src/main/java/com/exxeta/iss/sonar/esql/codecoverage/TraceParser.java @@ -21,6 +21,8 @@ import com.exxeta.iss.sonar.esql.trace.InsertType; import com.exxeta.iss.sonar.esql.trace.UserTraceLog; import com.exxeta.iss.sonar.esql.trace.UserTraceType; +import org.sonar.api.utils.log.Logger; +import org.sonar.api.utils.log.Loggers; import org.xml.sax.Attributes; import org.xml.sax.SAXException; import org.xml.sax.helpers.DefaultHandler; @@ -31,6 +33,7 @@ public class TraceParser extends DefaultHandler { + public static final Logger LOG = Loggers.get(TraceParser.class.getName()); private UserTraceLog result = null; private UserTraceType userTraceType; @@ -62,6 +65,8 @@ public void startElement(String uri, String localName, String qName, Attributes userTraceType.getInsert().add(insertType); mapAttributes(attributes, insertType); break; + default: + LOG.warn("unsupported trace tag " + localName); } } @@ -74,6 +79,8 @@ public void endElement(String uri, String localName, String qName) throws SAXExc userTraceType = null; case "Insert": insertType = null; + default: + LOG.warn("unsupported trace tag " + localName); } } @@ -82,25 +89,25 @@ private void mapAttributes(Attributes attributes, Object obj) { BeanInfo beanInfo = Introspector.getBeanInfo(obj.getClass()); for (int i = 0; i < attributes.getLength(); i++) { String localName = attributes.getLocalName(i); - for (PropertyDescriptor pd : beanInfo.getPropertyDescriptors()){ - if (pd.getWriteMethod()!=null && pd.getName().equals(localName)){ + for (PropertyDescriptor pd : beanInfo.getPropertyDescriptors()) { + if (pd.getWriteMethod() != null && pd.getName().equals(localName)) { if (pd.getPropertyType() == String.class) { pd.getWriteMethod().invoke(obj, attributes.getValue(i)); - } else if (pd.getPropertyType()==Integer.class){ + } else if (pd.getPropertyType() == Integer.class) { pd.getWriteMethod().invoke(obj, Integer.parseInt(attributes.getValue(i))); } } } } } catch (Exception e) { - System.err.println("Cannot map attribute"); + LOG.error("Cannot map attribute"); } } @Override public void characters(char[] ch, int start, int length) throws SAXException { if (insertType != null) { - if (insertType.getValue()!=null){ + if (insertType.getValue() != null) { insertType.setValue(insertType.getValue() + new String(ch, start, length)); } else { insertType.setValue(new String(ch, start, length));