From e649d92002ccd1f8e91b753c5d29be8ca8adb73e Mon Sep 17 00:00:00 2001 From: Jean-Baptiste Lievremont Date: Wed, 26 Nov 2014 14:36:20 +0100 Subject: [PATCH] SONAR-5819 Add highlighting in api/sources/lines --- .../server/source/HtmlSourceDecorator.java | 17 ++++++++++++ .../index/SourceLineResultSetIterator.java | 5 +++- .../sonar/server/source/ws/LinesAction.java | 7 +++-- .../source/HtmlSourceDecoratorTest.java | 26 ++++++++++++++++++- .../SourceLineResultSetIteratorTest.java | 10 +++---- .../server/source/ws/LinesActionTest.java | 21 ++++++++++++++- .../sonar/server/source/ws/SourcesWsTest.java | 3 ++- .../ws/LinesActionTest/show_source.json | 6 ++--- .../show_source_with_params_from_and_to.json | 2 +- 9 files changed, 82 insertions(+), 15 deletions(-) diff --git a/server/sonar-server/src/main/java/org/sonar/server/source/HtmlSourceDecorator.java b/server/sonar-server/src/main/java/org/sonar/server/source/HtmlSourceDecorator.java index cfde941a219..c205688eb52 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/source/HtmlSourceDecorator.java +++ b/server/sonar-server/src/main/java/org/sonar/server/source/HtmlSourceDecorator.java @@ -75,6 +75,23 @@ public class HtmlSourceDecorator implements ServerComponent { return null; } + @CheckForNull + public String getDecoratedSourceAsHtml(@Nullable String sourceLine, @Nullable String highlighting) { + Collection snapshotDataEntries = Lists.newArrayList(); + if (highlighting != null) { + SnapshotDataDto highlightingDto = new SnapshotDataDto(); + highlightingDto.setData(highlighting); + highlightingDto.setDataType(SnapshotDataTypes.SYNTAX_HIGHLIGHTING); + snapshotDataEntries.add(highlightingDto); + } + List decoratedSource = decorate(sourceLine, snapshotDataEntries, 1, 1); + if (decoratedSource == null) { + return null; + } else { + return decoratedSource.get(0); + } + } + @CheckForNull private List decorate(@Nullable String snapshotSource, Collection snapshotDataEntries, @Nullable Integer from, @Nullable Integer to) { if (snapshotSource != null) { diff --git a/server/sonar-server/src/main/java/org/sonar/server/source/index/SourceLineResultSetIterator.java b/server/sonar-server/src/main/java/org/sonar/server/source/index/SourceLineResultSetIterator.java index e850ffb7bc9..94ebaf9ad24 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/source/index/SourceLineResultSetIterator.java +++ b/server/sonar-server/src/main/java/org/sonar/server/source/index/SourceLineResultSetIterator.java @@ -100,7 +100,10 @@ class SourceLineResultSetIterator extends ResultSetIteratorpackage org.polop;"); + } + + @Test + public void should_ignore_missing_highlighting() { + String sourceLine = " if (toto < 42) {"; + assertThat(sourceDecorator.getDecoratedSourceAsHtml(sourceLine, null)).isEqualTo(" if (toto < 42) {"); + assertThat(sourceDecorator.getDecoratedSourceAsHtml(sourceLine, "")).isEqualTo(" if (toto < 42) {"); + } + + @Test + public void should_ignore_null_source() { + assertThat(sourceDecorator.getDecoratedSourceAsHtml(null, null)).isNull(); + } } + diff --git a/server/sonar-server/src/test/java/org/sonar/server/source/index/SourceLineResultSetIteratorTest.java b/server/sonar-server/src/test/java/org/sonar/server/source/index/SourceLineResultSetIteratorTest.java index 2e9557593d4..a41f02c20ba 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/source/index/SourceLineResultSetIteratorTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/source/index/SourceLineResultSetIteratorTest.java @@ -61,10 +61,10 @@ public class SourceLineResultSetIteratorTest { db.prepareDbUnit(getClass(), "source-with-scm.xml"); Connection connection = db.openConnection(); PreparedStatement stmt = connection.prepareStatement("UPDATE file_sources SET data = ? WHERE id=1"); - stmt.setString(1, "aef12a,alice,2014-04-25T12:34:56+0100,,class Foo {\r\n" + - "abe465,bob,2014-07-25T12:34:56+0100,, // Empty\r\n" + - "afb789,carol,2014-03-23T12:34:56+0100,,}\r\n" + - "afb789,carol,2014-03-23T12:34:56+0100,,\r\n"); + stmt.setString(1, "aef12a,alice,2014-04-25T12:34:56+0100,,,,polop,class Foo {\r\n" + + "abe465,bob,2014-07-25T12:34:56+0100,,,,, // Empty\r\n" + + "afb789,carol,2014-03-23T12:34:56+0100,,,,,}\r\n" + + "afb789,carol,2014-03-23T12:34:56+0100,,,,,\r\n"); stmt.executeUpdate(); SourceLineResultSetIterator iterator = SourceLineResultSetIterator.create(dbClient, connection, 0L); @@ -79,7 +79,7 @@ public class SourceLineResultSetIteratorTest { assertThat(firstLine.scmAuthor()).isEqualTo("alice"); // TODO Sanitize usage of fscking dates // assertThat(firstLine.scmDate()).isEqualTo(DateUtils.parseDateTime("2014-04-25T12:34:56+0100")); - assertThat(firstLine.highlighting()).isEmpty(); + assertThat(firstLine.highlighting()).isEqualTo("polop"); assertThat(firstLine.source()).isEqualTo("class Foo {"); } diff --git a/server/sonar-server/src/test/java/org/sonar/server/source/ws/LinesActionTest.java b/server/sonar-server/src/test/java/org/sonar/server/source/ws/LinesActionTest.java index ab942f8f74d..523916f7b16 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/source/ws/LinesActionTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/source/ws/LinesActionTest.java @@ -20,15 +20,19 @@ package org.sonar.server.source.ws; import com.google.common.collect.ImmutableMap; +import org.apache.commons.lang.StringEscapeUtils; import org.elasticsearch.common.collect.Lists; import org.elasticsearch.common.collect.Maps; import org.junit.Before; import org.junit.Test; import org.junit.runner.RunWith; import org.mockito.Mock; +import org.mockito.invocation.InvocationOnMock; import org.mockito.runners.MockitoJUnitRunner; +import org.mockito.stubbing.Answer; import org.sonar.server.exceptions.NotFoundException; import org.sonar.server.search.BaseNormalizer; +import org.sonar.server.source.HtmlSourceDecorator; import org.sonar.server.source.index.SourceLineDoc; import org.sonar.server.source.index.SourceLineIndex; import org.sonar.server.source.index.SourceLineIndexDefinition; @@ -52,6 +56,9 @@ public class LinesActionTest { @Mock SourceLineIndex sourceLineIndex; + @Mock + HtmlSourceDecorator htmlSourceDecorator; + WsTester tester; @Before @@ -61,10 +68,18 @@ public class LinesActionTest { mock(ShowAction.class), mock(RawAction.class), mock(ScmAction.class), - new LinesAction(sourceLineIndex), + new LinesAction(sourceLineIndex, htmlSourceDecorator), mock(HashAction.class) ) ); + when(htmlSourceDecorator.getDecoratedSourceAsHtml(anyString(), anyString())).thenAnswer(new Answer() { + @Override + public String answer(InvocationOnMock invocation) throws Throwable { + return "" + + StringEscapeUtils.escapeHtml((String) invocation.getArguments()[0]) + + ""; + } + }); } @Test @@ -80,6 +95,7 @@ public class LinesActionTest { .put(SourceLineIndexDefinition.FIELD_SCM_DATE, scmDate) .put(SourceLineIndexDefinition.FIELD_SCM_AUTHOR, "polop") .put(SourceLineIndexDefinition.FIELD_SOURCE, "class Polop {") + .put(SourceLineIndexDefinition.FIELD_HIGHLIGHTING, "h1") .put(BaseNormalizer.UPDATED_AT_FIELD, updatedAt) .build()); SourceLineDoc line2 = new SourceLineDoc(ImmutableMap.builder() @@ -90,6 +106,7 @@ public class LinesActionTest { .put(SourceLineIndexDefinition.FIELD_SCM_DATE, scmDate) .put(SourceLineIndexDefinition.FIELD_SCM_AUTHOR, "polop") .put(SourceLineIndexDefinition.FIELD_SOURCE, " // Empty") + .put(SourceLineIndexDefinition.FIELD_HIGHLIGHTING, "h2") .put(BaseNormalizer.UPDATED_AT_FIELD, updatedAt) .build()); SourceLineDoc line3 = new SourceLineDoc(ImmutableMap.builder() @@ -100,6 +117,7 @@ public class LinesActionTest { .put(SourceLineIndexDefinition.FIELD_SCM_DATE, scmDate) .put(SourceLineIndexDefinition.FIELD_SCM_AUTHOR, "polop") .put(SourceLineIndexDefinition.FIELD_SOURCE, "}") + .put(SourceLineIndexDefinition.FIELD_HIGHLIGHTING, "h3") .put(BaseNormalizer.UPDATED_AT_FIELD, updatedAt) .build()); when(sourceLineIndex.getLines(eq(componentUuid), anyInt(), anyInt())).thenReturn(newArrayList( @@ -138,6 +156,7 @@ public class LinesActionTest { fieldMap.put(SourceLineIndexDefinition.FIELD_SCM_DATE, null); fieldMap.put(SourceLineIndexDefinition.FIELD_SCM_AUTHOR, "polop"); fieldMap.put(SourceLineIndexDefinition.FIELD_SOURCE, "}"); + fieldMap.put(SourceLineIndexDefinition.FIELD_HIGHLIGHTING, ""); fieldMap.put(BaseNormalizer.UPDATED_AT_FIELD, new Date()); when(sourceLineIndex.getLines(fileKey, 3, 3)).thenReturn(newArrayList( new SourceLineDoc(fieldMap) diff --git a/server/sonar-server/src/test/java/org/sonar/server/source/ws/SourcesWsTest.java b/server/sonar-server/src/test/java/org/sonar/server/source/ws/SourcesWsTest.java index 72c393d9051..cb2d10387b4 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/source/ws/SourcesWsTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/source/ws/SourcesWsTest.java @@ -24,6 +24,7 @@ import org.junit.Test; import org.sonar.api.server.ws.WebService; import org.sonar.core.source.db.FileSourceDao; import org.sonar.server.db.DbClient; +import org.sonar.server.source.HtmlSourceDecorator; import org.sonar.server.source.SourceService; import org.sonar.server.source.index.SourceLineIndex; import org.sonar.server.ws.WsTester; @@ -36,7 +37,7 @@ public class SourcesWsTest { ShowAction showAction = new ShowAction(mock(SourceService.class)); RawAction rawAction = new RawAction(mock(DbClient.class), mock(SourceService.class)); ScmAction scmAction = new ScmAction(mock(SourceService.class), new ScmWriter()); - LinesAction linesAction = new LinesAction(mock(SourceLineIndex.class)); + LinesAction linesAction = new LinesAction(mock(SourceLineIndex.class), mock(HtmlSourceDecorator.class)); HashAction hashAction = new HashAction(mock(DbClient.class), mock(FileSourceDao.class)); WsTester tester = new WsTester(new SourcesWs(showAction, rawAction, scmAction, linesAction, hashAction)); diff --git a/server/sonar-server/src/test/resources/org/sonar/server/source/ws/LinesActionTest/show_source.json b/server/sonar-server/src/test/resources/org/sonar/server/source/ws/LinesActionTest/show_source.json index 27d36186e5c..1aecc066d5d 100644 --- a/server/sonar-server/src/test/resources/org/sonar/server/source/ws/LinesActionTest/show_source.json +++ b/server/sonar-server/src/test/resources/org/sonar/server/source/ws/LinesActionTest/show_source.json @@ -1,19 +1,19 @@ { "sources": [ { - "code": "class Polop {", + "code": "class Polop {", "line": 1, "scmAuthor": "polop", "scmRevision": "cafebabe" }, { - "code": " // Empty", + "code": " // Empty", "line": 2, "scmAuthor": "polop", "scmRevision": "cafebabe" }, { - "code": "}", + "code": "}", "line": 3, "scmAuthor": "polop", "scmRevision": "cafebabe" diff --git a/server/sonar-server/src/test/resources/org/sonar/server/source/ws/LinesActionTest/show_source_with_params_from_and_to.json b/server/sonar-server/src/test/resources/org/sonar/server/source/ws/LinesActionTest/show_source_with_params_from_and_to.json index ba2a4c6e52b..73dcf29d17a 100644 --- a/server/sonar-server/src/test/resources/org/sonar/server/source/ws/LinesActionTest/show_source_with_params_from_and_to.json +++ b/server/sonar-server/src/test/resources/org/sonar/server/source/ws/LinesActionTest/show_source_with_params_from_and_to.json @@ -1,7 +1,7 @@ { "sources": [ { - "code": "}", + "code": "}", "line": 3, "scmAuthor": "polop", "scmRevision": "cafebabe" -- 2.39.5