package de.itemis.tooling.xturtle.plugintests;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.eclipse.emf.common.util.URI;
import org.eclipse.jface.text.contentassist.ICompletionProposal;
import org.eclipse.xtext.ISetup;
import org.eclipse.xtext.junit4.ui.AbstractContentAssistProcessorTest;
import org.eclipse.xtext.junit4.ui.ContentAssistProcessorTestBuilder;
import org.eclipse.xtext.resource.XtextResource;
import org.eclipse.xtext.ui.editor.contentassist.ConfigurableCompletionProposal;
import org.eclipse.xtext.ui.editor.contentassist.ReplacementTextApplier;
import org.eclipse.xtext.util.Strings;
import org.junit.Assert;
import org.junit.BeforeClass;
import org.junit.Test;
import com.google.inject.Injector;
import de.itemis.tooling.xturtle.XturtleUiInjectorProvider;
@SuppressWarnings("restriction")
public class TurtleContentAssistTest extends AbstractContentAssistProcessorTest {
private static final int NL_LENGHT=Strings.newLine().length();
private static int counter=1;
int preInfixOffset;
@BeforeClass
public static void useSI(){
useStaticInjector=false;
}
@Override
protected XtextResource doGetResource(InputStream in, URI uri)
throws Exception {
return super.doGetResource(in, URI.createURI("file://testmodel"+(counter++)+".ttl"));
}
@Test
public void simpleCAfailingAfterFirstLexerModifications() throws Exception{
newBuilder().assertProposal("@prefix");
newBuilder().appendNl("@prefix x:</tada>.")
.assertProposal("x:").apply().append("a ")
.assertProposal("x:").apply()
.assertProposal(":a");
}
@Test
public void emptyPrefixProposal() throws Exception{
newBuilder().appendNl("@prefix :</tada>.")
.assertProposal(":").apply().append("a ")
.assertProposal(":").apply()
.assertProposal(":a");
}
@Test
public void prefixWithNonemptyFragment() throws Exception{
newBuilder().appendNl("@prefix :<http://www.example.de/tidum#ta>.")
.appendNl("<http://www.example.de/tidum#tada> ")
.assertProposal(":").apply()
.assertProposal(":da");
}
@Test
public void prefixCC() throws Exception{
newBuilder().appendNl("@prefix ")
.assertProposal("rdf").apply()
.assertProposal(":").apply()
.assertProposal("<http://www.w3.org/1999/02/22-rdf-syntax-ns#>");
}
@Test
public void languageProposals() throws Exception{
newBuilder().appendNl("<> a \"foo\"").assertProposal("@en");
newBuilder().appendNl("<> a \"foo\"").assertProposal("@de");
}
//infixlines start at offset 38
private ContentAssistProcessorTestBuilder getBuilder(String ... infixLines)throws Exception{
String line1="@prefix x:</tada>.";
String line2="x:test1 a <tada>.";
preInfixOffset=line1.length()+NL_LENGHT+line2.length()+NL_LENGHT;
ContentAssistProcessorTestBuilder result=newBuilder()
.appendNl(line1)
.appendNl(line2);
for (String string : infixLines) {
result=result.appendNl(string);
}
result=result.appendNl("x:test2 a <tada>.");
return result;
}
@Test
public void referenceInSimpleTriple() throws Exception{
ICompletionProposal[] proposals = getBuilder("x:a x:").computeCompletionProposals(preInfixOffset+6);
checkProposalExists(":a", proposals);
checkProposalExists(":test1", proposals);
//at this point the following defintion of x:test2 is not known, as
//the parser has no way of knowing that a new triple has started
//checkProposalExists(":test2", proposals);
proposals = getBuilder("x:a x: .").computeCompletionProposals(preInfixOffset+6);
checkProposalExists(":a", proposals);
checkProposalExists(":test1", proposals);
//here the parser has the triple end to indicate that x:test2 is a new subject
checkProposalExists(":test2", proposals);
}
@Test
//bug reported by Alexander Willner
//reason was that the language tag for a string literal caused the partitioner
//to fail - none of the following triples was known, fixed with a grammar change
//making the language a terminal rule
public void referenceInTripleWithStringLiteral() throws Exception{
ICompletionProposal[] proposals = getBuilder("x:a x: ;","a 'abc'@de .").computeCompletionProposals(preInfixOffset+6);
checkProposalExists(":a", proposals);
checkProposalExists(":test1", proposals);
checkProposalExists(":test2", proposals);
int infixOffset="x:a a a 'abc'@de;".length()+NL_LENGHT+6;
proposals = getBuilder("x:a a a 'abc'@de;","x.a x: .").computeCompletionProposals(preInfixOffset+infixOffset);
checkProposalExists(":a", proposals);
checkProposalExists(":test1", proposals);
checkProposalExists(":test2", proposals);
}
void checkProposalExists(String expectedProposal, ICompletionProposal[] proposals){
for(ICompletionProposal proposal: proposals) {
if (expectedProposal.equals(toString(proposal))) {
return;
}
}
Assert.fail("No such proposal: " + expectedProposal + " Found: " + toString(proposals));
}
protected String toString(ICompletionProposal proposal) {
String proposedText = proposal.getDisplayString();
if (proposal instanceof ConfigurableCompletionProposal) {
ConfigurableCompletionProposal configurableProposal = (ConfigurableCompletionProposal) proposal;
proposedText = configurableProposal.getReplacementString();
if (configurableProposal.getTextApplier() instanceof ReplacementTextApplier)
proposedText = ((ReplacementTextApplier) configurableProposal.getTextApplier()).getActualReplacementString(configurableProposal);
}
return proposedText;
}
public List<String> toString(ICompletionProposal[] proposals) {
if (proposals == null)
return Collections.emptyList();
List<String> res = new ArrayList<String>(proposals.length);
for (ICompletionProposal proposal : proposals) {
String proposedText = toString(proposal);
res.add(proposedText);
}
Collections.sort(res);
return res;
}
@Override
protected ISetup doGetSetup() {
return new ISetup() {
// @Override
public Injector createInjectorAndDoEMFRegistration() {
return new XturtleUiInjectorProvider().getInjector();
}
};
}
}