/*
* Copyright 2016 Nokia Solutions and Networks
* Licensed under the Apache License, Version 2.0,
* see license.txt file for details.
*/
package org.robotframework.ide.eclipse.main.plugin.hyperlink.detectors;
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.mock;
import static org.mockito.Mockito.when;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.List;
import org.eclipse.core.resources.IFile;
import org.eclipse.core.runtime.CoreException;
import org.eclipse.jface.text.ITextViewer;
import org.eclipse.jface.text.Region;
import org.eclipse.jface.text.hyperlink.IHyperlink;
import org.junit.AfterClass;
import org.junit.BeforeClass;
import org.junit.ClassRule;
import org.junit.Test;
import org.rf.ide.core.project.RobotProjectConfig;
import org.rf.ide.core.project.RobotProjectConfig.LibraryType;
import org.rf.ide.core.project.RobotProjectConfig.ReferencedLibrary;
import org.robotframework.ide.eclipse.main.plugin.hyperlink.CompoundHyperlink;
import org.robotframework.ide.eclipse.main.plugin.hyperlink.KeywordDocumentationHyperlink;
import org.robotframework.ide.eclipse.main.plugin.hyperlink.KeywordInLibrarySourceHyperlink;
import org.robotframework.ide.eclipse.main.plugin.hyperlink.RegionsHyperlink;
import org.robotframework.ide.eclipse.main.plugin.hyperlink.SuiteFileSourceRegionHyperlink;
import org.robotframework.ide.eclipse.main.plugin.hyperlink.UserKeywordDocumentationHyperlink;
import org.robotframework.ide.eclipse.main.plugin.mockdocument.Document;
import org.robotframework.ide.eclipse.main.plugin.model.RobotKeywordDefinition;
import org.robotframework.ide.eclipse.main.plugin.model.RobotKeywordsSection;
import org.robotframework.ide.eclipse.main.plugin.model.RobotModel;
import org.robotframework.ide.eclipse.main.plugin.model.RobotProject;
import org.robotframework.ide.eclipse.main.plugin.model.RobotSuiteFile;
import org.robotframework.ide.eclipse.main.plugin.project.library.KeywordSpecification;
import org.robotframework.ide.eclipse.main.plugin.project.library.LibrarySpecification;
import org.robotframework.red.junit.ProjectProvider;
import com.google.common.base.Splitter;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Range;
import com.google.common.collect.RangeSet;
import com.google.common.collect.TreeRangeSet;
public class SourceHyperlinksToKeywordsDetectorTest {
@ClassRule
public static ProjectProvider projectProvider = new ProjectProvider(SourceHyperlinksToKeywordsDetectorTest.class);
private static ReferencedLibrary lib;
private static LibrarySpecification libSpec;
@BeforeClass
public static void beforeSuite() throws Exception {
projectProvider.createFile("file.robot",
"*** Keywords ***",
"res_kw",
" log 10");
lib = new ReferencedLibrary();
lib.setType(LibraryType.PYTHON.toString());
lib.setName("testlib");
lib.setPath(projectProvider.getProject().getName());
final RobotProjectConfig config = new RobotProjectConfig();
config.addReferencedLibrary(lib);
projectProvider.createFile("testlib.py");
projectProvider.configure(config);
final KeywordSpecification kwSpec = new KeywordSpecification();
kwSpec.setFormat("ROBOT");
kwSpec.setName("lib_kw");
kwSpec.setArguments(new ArrayList<String>());
kwSpec.setDocumentation("");
libSpec = new LibrarySpecification();
libSpec.setName("testlib");
libSpec.getKeywords().add(kwSpec);
}
@AfterClass
public static void afterSuite() {
lib = null;
libSpec = null;
}
@Test
public void noHyperlinksAreProvided_whenRegionsIsOutsideOfFile() throws Exception {
final IFile file = projectProvider.createFile("f0.robot",
"*** Test Cases ***",
"case",
" Log 10");
final RobotSuiteFile suiteFile = new RobotModel().createSuiteFile(file);
final Document document = new Document(getContent(file));
final ITextViewer textViewer = mock(ITextViewer.class);
when(textViewer.getDocument()).thenReturn(document);
final SourceHyperlinksToKeywordsDetector detector = new SourceHyperlinksToKeywordsDetector(suiteFile);
assertThat(detector.detectHyperlinks(textViewer, new Region(-100, 1), true)).isNull();
assertThat(detector.detectHyperlinks(textViewer, new Region(100, 1), true)).isNull();
}
@Test
public void noHyperlinksAreProvided_whenGivenLocationIsNotOverKeyword() throws Exception {
final IFile file = projectProvider.createFile("f1.robot",
"*** Test Cases ***",
"case",
" kw1 ${x}",
" kw2 ${y}",
"*** Keywords ***",
"kw1",
"kw2");
final RobotSuiteFile suiteFile = new RobotModel().createSuiteFile(file);
final Document document = new Document(getContent(file));
final ITextViewer textViewer = mock(ITextViewer.class);
when(textViewer.getDocument()).thenReturn(document);
final int begin1 = 26;
final int begin2 = 38;
final int begin3 = 65;
final int begin4 = 69;
assertThat(document.get(begin1, 3)).isEqualTo("kw1");
assertThat(document.get(begin2, 3)).isEqualTo("kw2");
assertThat(document.get(begin3, 3)).isEqualTo("kw1");
assertThat(document.get(begin4, 3)).isEqualTo("kw2");
final RangeSet<Integer> varsPositions = TreeRangeSet.create();
varsPositions.add(Range.closed(begin1, begin1 + 3));
varsPositions.add(Range.closed(begin2, begin2 + 3));
varsPositions.add(Range.closed(begin3, begin3 + 3));
varsPositions.add(Range.closed(begin4, begin4 + 3));
final SourceHyperlinksToKeywordsDetector detector = new SourceHyperlinksToKeywordsDetector(suiteFile);
for (int i = 0; i < document.getLength(); i++) {
if (!varsPositions.contains(i)) {
assertThat(detector.detectHyperlinks(textViewer, new Region(i, 1), true)).isNull();
}
}
}
@Test
public void noHyperlinksAreProvided_whenKeywordIsNotLocatedInKeywordsTable() throws Exception {
final IFile file = projectProvider.createFile("f2.robot",
"*** Test Cases ***",
"case",
" kw1 ${x}");
final RobotModel model = new RobotModel();
final RobotSuiteFile suiteFile = model.createSuiteFile(file);
final Document document = new Document(getContent(file));
final ITextViewer textViewer = mock(ITextViewer.class);
when(textViewer.getDocument()).thenReturn(document);
final int begin = 26;
assertThat(document.get(begin, 3)).isEqualTo("kw1");
final SourceHyperlinksToKeywordsDetector detector = new SourceHyperlinksToKeywordsDetector(model, suiteFile);
assertThat(detector.detectHyperlinks(textViewer, new Region(begin + 1, 1), true)).isNull();
}
@Test
public void noHyperlinksAreProvided_whenKeywordIsNotLocatedInResourceFile() throws Exception {
final IFile file = projectProvider.createFile("f3.robot",
"*** Test Cases ***",
"case",
" kw1 ${x}",
"*** Settings ***",
"Resource file.robot");
final RobotModel model = new RobotModel();
final RobotSuiteFile suiteFile = model.createSuiteFile(file);
final Document document = new Document(getContent(file));
final ITextViewer textViewer = mock(ITextViewer.class);
when(textViewer.getDocument()).thenReturn(document);
final int begin = 26;
assertThat(document.get(begin, 3)).isEqualTo("kw1");
final SourceHyperlinksToKeywordsDetector detector = new SourceHyperlinksToKeywordsDetector(model, suiteFile);
assertThat(detector.detectHyperlinks(textViewer, new Region(begin + 1, 1), true)).isNull();
}
@Test
public void noHyperlinksAreProvided_whenKeywordIsNotLocatedInLibrary() throws Exception {
final IFile file = projectProvider.createFile("f4.robot",
"*** Test Cases ***",
"case",
" some_kw ${x}",
"*** Settings ***",
"Library testlib");
final RobotModel model = new RobotModel();
final RobotSuiteFile suiteFile = model.createSuiteFile(file);
final Document document = new Document(getContent(file));
final RobotProject project = suiteFile.getProject();
project.setStandardLibraries(ImmutableMap.<String, LibrarySpecification> of());
project.setReferencedLibraries(ImmutableMap.of(lib, libSpec));
final ITextViewer textViewer = mock(ITextViewer.class);
when(textViewer.getDocument()).thenReturn(document);
final int begin = 26;
assertThat(document.get(begin, 7)).isEqualTo("some_kw");
final SourceHyperlinksToKeywordsDetector detector = new SourceHyperlinksToKeywordsDetector(model, suiteFile);
assertThat(detector.detectHyperlinks(textViewer, new Region(begin + 1, 1), true)).isNull();
}
@Test
public void hyperlinksAreProvided_whenKeywordIsLocatedInKeywordsTable() throws Exception {
final IFile file = projectProvider.createFile("f5.robot",
"*** Test Cases ***",
"case",
" kw1 ${x}",
"*** Keywords ***",
"kw1");
final RobotModel model = new RobotModel();
final RobotSuiteFile suiteFile = model.createSuiteFile(file);
final RobotKeywordDefinition kw1 = suiteFile.findSection(RobotKeywordsSection.class).get().getChildren().get(0);
final Document document = new Document(getContent(file));
final ITextViewer textViewer = mock(ITextViewer.class);
when(textViewer.getDocument()).thenReturn(document);
final int begin = 26;
assertThat(document.get(begin, 3)).isEqualTo("kw1");
final SourceHyperlinksToKeywordsDetector detector = new SourceHyperlinksToKeywordsDetector(model, suiteFile);
final IHyperlink[] hyperlinks = detector.detectHyperlinks(textViewer, new Region(begin + 1, 1), true);
assertThat(hyperlinks).hasSize(2);
assertThat(hyperlinks[0]).isInstanceOf(RegionsHyperlink.class);
assertThat(((RegionsHyperlink) hyperlinks[0]).getDestinationRegion()).isEqualTo(new Region(53, 3));
assertThat(hyperlinks[1]).isInstanceOf(UserKeywordDocumentationHyperlink.class);
assertThat(((UserKeywordDocumentationHyperlink) hyperlinks[1]).getDestinationKeyword()).isSameAs(kw1);
}
@Test
public void hyperlinksAreProvided_whenKeywordIsLocatedInResourceFile() throws Exception {
final IFile file = projectProvider.createFile("f6.robot",
"*** Test Cases ***",
"case",
" res_kw ${x}",
"*** Settings ***",
"Resource file.robot");
final RobotModel model = new RobotModel();
final RobotSuiteFile suiteFile = model.createSuiteFile(file);
final RobotSuiteFile resSuiteFile = model.createSuiteFile(projectProvider.getFile("file.robot"));
final RobotKeywordDefinition resKw = resSuiteFile.findSection(RobotKeywordsSection.class).get()
.getChildren().get(0);
final Document document = new Document(getContent(file));
final ITextViewer textViewer = mock(ITextViewer.class);
when(textViewer.getDocument()).thenReturn(document);
final int begin = 26;
assertThat(document.get(begin, 6)).isEqualTo("res_kw");
final SourceHyperlinksToKeywordsDetector detector = new SourceHyperlinksToKeywordsDetector(model, suiteFile);
final IHyperlink[] hyperlinks = detector.detectHyperlinks(textViewer, new Region(begin + 1, 1), true);
assertThat(hyperlinks).hasSize(2);
assertThat(hyperlinks[0]).isInstanceOf(SuiteFileSourceRegionHyperlink.class);
assertThat(((SuiteFileSourceRegionHyperlink) hyperlinks[0]).getDestinationFile()).isSameAs(resSuiteFile);
assertThat(((SuiteFileSourceRegionHyperlink) hyperlinks[0]).getDestinationRegion())
.isEqualTo(new Region(17, 6));
assertThat(hyperlinks[1]).isInstanceOf(UserKeywordDocumentationHyperlink.class);
assertThat(((UserKeywordDocumentationHyperlink) hyperlinks[1]).getDestinationKeyword()).isSameAs(resKw);
}
@Test
public void hyperlinksAreProvided_whenKeywordIsLocatedInLibrary() throws Exception {
final IFile file = projectProvider.createFile("f7.robot",
"*** Test Cases ***",
"case",
" lib_kw ${x}",
"*** Settings ***",
"Library testlib");
final RobotModel model = new RobotModel();
final RobotSuiteFile suiteFile = model.createSuiteFile(file);
final Document document = new Document(getContent(file));
final RobotProject project = suiteFile.getProject();
project.setStandardLibraries(ImmutableMap.<String, LibrarySpecification> of());
project.setReferencedLibraries(ImmutableMap.of(lib, libSpec));
final ITextViewer textViewer = mock(ITextViewer.class);
when(textViewer.getDocument()).thenReturn(document);
final int begin = 26;
assertThat(document.get(begin, 6)).isEqualTo("lib_kw");
final SourceHyperlinksToKeywordsDetector detector = new SourceHyperlinksToKeywordsDetector(model, suiteFile);
final IHyperlink[] hyperlinks = detector.detectHyperlinks(textViewer, new Region(begin + 1, 1), true);
assertThat(hyperlinks).hasSize(2);
assertThat(hyperlinks[0]).isInstanceOf(KeywordInLibrarySourceHyperlink.class);
assertThat(((KeywordInLibrarySourceHyperlink) hyperlinks[0]).getDestinationSpecification()).isSameAs(libSpec);
assertThat(hyperlinks[1]).isInstanceOf(KeywordDocumentationHyperlink.class);
assertThat(((KeywordDocumentationHyperlink) hyperlinks[1]).getDestinationLibrarySpecification())
.isSameAs(libSpec);
assertThat(((KeywordDocumentationHyperlink) hyperlinks[1]).getDestinationKeywordSpecification())
.isSameAs(libSpec.getKeywords().get(0));
}
@Test
public void hyperlinksAreProvided_whenKeywordIsUsedInGherkinStyle() throws Exception {
final IFile file = projectProvider.createFile("f8.robot",
"*** Test Cases ***",
"case",
" given kw",
" and kw",
" but kw",
" when kw",
" then kw",
"*** Keywords ***",
"kw");
final RobotModel model = new RobotModel();
final RobotSuiteFile suiteFile = model.createSuiteFile(file);
final Document document = new Document(getContent(file));
final ITextViewer textViewer = mock(ITextViewer.class);
when(textViewer.getDocument()).thenReturn(document);
final int[] begins = new int[] { 26, 37, 46, 55, 65 };
final int[] prefixLenghts = new int[] { 6, 4, 4, 5, 5 };
assertThat(document.get(begins[0], 8)).isEqualTo("given kw");
assertThat(document.get(begins[1], 6)).isEqualTo("and kw");
assertThat(document.get(begins[2], 6)).isEqualTo("but kw");
assertThat(document.get(begins[3], 7)).isEqualTo("when kw");
assertThat(document.get(begins[4], 7)).isEqualTo("then kw");
final SourceHyperlinksToKeywordsDetector detector = new SourceHyperlinksToKeywordsDetector(model, suiteFile);
for (int i = 0; i < begins.length; i++) {
final IHyperlink[] hyperlinks = detector.detectHyperlinks(textViewer, new Region(begins[i] + 1, 1), true);
assertThat(((RegionsHyperlink) hyperlinks[0]).getHyperlinkRegion()).isEqualTo(new Region(begins[i] + prefixLenghts[i], 2));
assertThat(((RegionsHyperlink) hyperlinks[0]).getDestinationRegion()).isEqualTo(new Region(90, 2));
}
}
@Test
public void multipleHyperlinksAreProvided_whenKeywordIsDefinedMultipleTimes() throws Exception {
final IFile file = projectProvider.createFile("f9.robot",
"*** Test Cases ***",
"case",
" res_kw ${x}",
"*** Keywords ***",
"res_kw",
"*** Settings ***",
"Resource file.robot");
final RobotModel model = new RobotModel();
final RobotSuiteFile suiteFile = model.createSuiteFile(file);
final RobotKeywordDefinition kw = suiteFile.findSection(RobotKeywordsSection.class)
.get().getChildren().get(0);
final Document document = new Document(getContent(file));
final ITextViewer textViewer = mock(ITextViewer.class);
when(textViewer.getDocument()).thenReturn(document);
final int begin = 26;
assertThat(document.get(begin, 6)).isEqualTo("res_kw");
final SourceHyperlinksToKeywordsDetector detector = new SourceHyperlinksToKeywordsDetector(model, suiteFile);
final IHyperlink[] hyperlinks = detector.detectHyperlinks(textViewer, new Region(begin + 1, 1), true);
assertThat(hyperlinks).hasSize(4);
assertThat(hyperlinks[0]).isInstanceOf(RegionsHyperlink.class);
assertThat(((RegionsHyperlink) hyperlinks[0]).getDestinationRegion()).isEqualTo(new Region(56, 6));
assertThat(hyperlinks[1]).isInstanceOf(UserKeywordDocumentationHyperlink.class);
assertThat(((UserKeywordDocumentationHyperlink) hyperlinks[1]).getDestinationKeyword()).isSameAs(kw);
assertThat(hyperlinks[2]).isInstanceOf(CompoundHyperlink.class);
assertThat(((CompoundHyperlink) hyperlinks[2]).getHyperlinks()).hasSize(2);
assertThat(((CompoundHyperlink) hyperlinks[2]).getHyperlinks().get(0)).isInstanceOf(RegionsHyperlink.class);
assertThat(((CompoundHyperlink) hyperlinks[2]).getHyperlinks().get(1)).isInstanceOf(SuiteFileSourceRegionHyperlink.class);
assertThat(hyperlinks[3]).isInstanceOf(CompoundHyperlink.class);
assertThat(((CompoundHyperlink) hyperlinks[3]).getHyperlinks()).hasSize(2);
assertThat(((CompoundHyperlink) hyperlinks[3]).getHyperlinks().get(0)).isInstanceOf(UserKeywordDocumentationHyperlink.class);
assertThat(((CompoundHyperlink) hyperlinks[3]).getHyperlinks().get(1)).isInstanceOf(UserKeywordDocumentationHyperlink.class);
}
private static List<String> getContent(final IFile file) {
try (InputStream stream = file.getContents()) {
return Splitter.on('\n').splitToList(projectProvider.getFileContent(file));
} catch (IOException | CoreException e) {
return new ArrayList<>();
}
}
}