diff options
author | Jon Bratseth <bratseth@gmail.com> | 2022-02-10 22:27:08 +0100 |
---|---|---|
committer | Jon Bratseth <bratseth@gmail.com> | 2022-02-10 22:27:08 +0100 |
commit | b2e547393fcb5c41c3657be7221ecef146ac9298 (patch) | |
tree | a45c8c9f1004646d2dcacd147a45a93e6f6a3330 /integration | |
parent | a1ff60175c83e27d2ff36996abf90f318b709c6a (diff) |
Unit test parent rank profiles
Diffstat (limited to 'integration')
13 files changed, 270 insertions, 225 deletions
diff --git a/integration/intellij/pom.xml b/integration/intellij/pom.xml index 94d8fd90f99..866f1887443 100644 --- a/integration/intellij/pom.xml +++ b/integration/intellij/pom.xml @@ -28,7 +28,7 @@ <skip>true</skip> </configuration> </plugin> - <!-- Gradle is also responsible for creating javadoc such that this task is skipped here. --> + <!-- Gradle is also responsible for creating javadoc so this task is skipped here. --> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-javadoc-plugin</artifactId> diff --git a/integration/intellij/src/main/bnf/ai/vespa/intellij/schema/parser/sd.bnf b/integration/intellij/src/main/bnf/ai/vespa/intellij/schema/parser/sd.bnf index 04368bf29af..cd5ce14ed89 100644 --- a/integration/intellij/src/main/bnf/ai/vespa/intellij/schema/parser/sd.bnf +++ b/integration/intellij/src/main/bnf/ai/vespa/intellij/schema/parser/sd.bnf @@ -30,7 +30,10 @@ ID_WITH_DASH_REG = 'regexp:[a-zA-Z_][a-zA-Z0-9_-]*' WHITE_SPACE = 'regexp:\s+' COMMENT = 'regexp:#.*' - SYMBOL = 'regexp:[!$|:{}(),.\[\]]' + SYMBOL = 'regexp:[!$|:{}().\[\]]' + COMMA = 'regexp:[,]' + //BLOCK_START = '{' + //BLOCK_END = '}' COMPARISON_OPERATOR = 'regexp:[<>]|(==)|(<=)|(>=)|(~=)' ARITHMETIC_OPERATOR = 'regexp:[\-+*/%]' INTEGER_REG = 'regexp:[0-9]+' @@ -55,11 +58,11 @@ SchemaFieldDefinition ::= field IdentifierVal type FieldTypeName '{' SchemaField } FieldTypeName ::= ("array" '<' (FieldTypeName | IdentifierVal) '>') | ("weightedset" '<' SingleValueFieldTypeName '>') | - ("map" '<' (FieldTypeName | IdentifierVal) ',' (FieldTypeName | IdentifierVal) '>') | TensorType | + ("map" '<' (FieldTypeName | IdentifierVal) COMMA (FieldTypeName | IdentifierVal) '>') | TensorType | (SingleValueFieldTypeName '[' ']') | SingleValueFieldTypeName private SingleValueFieldTypeName ::= "string" | "int" | "long" | "bool" | "byte" | "float" | "double" | "position" | "predicate" | "raw" | "uri" | "reference" '<' IdentifierVal '>' | "annotationreference" '<' IdentifierVal '>' | IdentifierVal -private TensorType ::= "tensor" ('<' ("float" | "double" | "int8" | "bfloat16") '>')? '(' TensorDimension (',' TensorDimension)* ')' +private TensorType ::= "tensor" ('<' ("float" | "double" | "int8" | "bfloat16") '>')? '(' TensorDimension (COMMA TensorDimension)* ')' private TensorDimension ::= WordWrapper (('{' '}') | ('[' INTEGER_REG ']')) SchemaFieldBody ::= DocumentFieldBodyOptions* // Fields of schemas and documents defined the same way here @@ -78,7 +81,7 @@ ImportFieldDefinition ::= import field IdentifierVal '.' IdentifierVal as Identi FieldSetDefinition ::= fieldset IdentifierVal '{' FieldSetBody '}' FieldSetBody ::= FieldSetBodyOptions* -private FieldSetBodyOptions ::= (fields ':' IdentifierVal (',' IdentifierVal)*) | QueryCommandDefinition | MatchDefinition +private FieldSetBodyOptions ::= (fields ':' IdentifierVal (COMMA IdentifierVal)*) | QueryCommandDefinition | MatchDefinition ConstantDefinition ::= constant IdentifierVal '{' ConstantBody '}' ConstantBody ::= ConstantBodyOptions* @@ -111,8 +114,8 @@ RankingExpression ::= FilePathExpr | ParenthesisedExpr | BooleanExpr | Arithmeti FilePathExpr ::= file ':' (FilePath | WordWrapper) -IfFunctionExpr ::= "if" '(' (InListRankingExpr | RankingExpression) ',' RankingExpression ',' RankingExpression ')' -InListRankingExpr ::= RankingExpression "in" '[' RankingExpression (',' RankingExpression)* ']' +IfFunctionExpr ::= "if" '(' (InListRankingExpr | RankingExpression) COMMA RankingExpression COMMA RankingExpression ')' +InListRankingExpr ::= RankingExpression "in" '[' RankingExpression (COMMA RankingExpression)* ']' BooleanExpr ::= RankingExpression COMPARISON_OPERATOR RankingExpression @@ -120,7 +123,7 @@ ArithmeticExpr ::= RankingExpression ARITHMETIC_OPERATOR RankingExpression QueryDefinitionExpr ::= QueryDefinition | ItemRawScoreDefinition -FunctionCallExpr ::= IdentifierWithDashVal '(' RankingExpression (',' RankingExpression)* ')' ('.' IdentifierWithDashVal)? +FunctionCallExpr ::= IdentifierWithDashVal '(' RankingExpression (COMMA RankingExpression)* ')' ('.' IdentifierWithDashVal)? ParenthesisedExpr ::= '(' RankingExpression ')' @@ -129,7 +132,7 @@ PrimitiveExpr ::= (('-')? INTEGER_REG) | (('-')? FLOAT_REG) | IdentifierVal | Ra //------------------------- //-- Rank Profile rules --- //------------------------- -RankProfileDefinition ::= (rank-profile | model) IdentifierWithDashVal (inherits IdentifierWithDashVal (',' IdentifierWithDashVal)*)? '{' RankProfileBody '}' +RankProfileDefinition ::= (rank-profile | model) IdentifierWithDashVal (inherits IdentifierWithDashVal (COMMA IdentifierWithDashVal)*)? '{' RankProfileBody '}' { mixin="ai.vespa.intellij.schema.psi.impl.SdNamedElementImpl" implements=["ai.vespa.intellij.schema.psi.SdDeclaration"] } @@ -167,10 +170,10 @@ private SecondPhaseBodyOptions ::= (rerank-count ':' INTEGER_REG) | ExpressionDe RankPropertiesDefinition ::= rank-properties '{' RankPropertiesBody '}' RankPropertiesBody ::= (RankPropertiesKey ':' RankPropertiesValue)+ -RankPropertiesKey ::= (IdentifierWithDashVal | STRING_REG | '(' | ')' | '.' | ',' | '$' | INTEGER_REG)+ +RankPropertiesKey ::= (IdentifierWithDashVal | STRING_REG | '(' | ')' | '.' | COMMA | '$' | INTEGER_REG)+ RankPropertiesValue ::= (('-')? INTEGER_REG) | (('-')? FLOAT_REG) | WORD_REG | IdentifierVal | STRING_REG -FunctionDefinition ::= (function | macro) inline? IdentifierVal ( '()' | '(' (ArgumentDefinition (',' ArgumentDefinition)*)? ')' ) +FunctionDefinition ::= (function | macro) inline? IdentifierVal ( '()' | '(' (ArgumentDefinition (COMMA ArgumentDefinition)*)? ')' ) '{' ExpressionDefinition '}' { mixin="ai.vespa.intellij.schema.psi.impl.SdNamedElementImpl" implements=["ai.vespa.intellij.schema.psi.SdFunctionDefinitionInterface" "ai.vespa.intellij.schema.psi.SdNamedElement"] @@ -201,7 +204,7 @@ ItemRawScoreDefinition ::= "itemRawScore" '(' IdentifierVal ')' //------------------------- //---- Document rules ----- //------------------------- -DocumentDefinition ::= document (IdentifierVal (inherits IdentifierVal (',' IdentifierVal)*)?)? '{' DocumentBody '}' +DocumentDefinition ::= document (IdentifierVal (inherits IdentifierVal (COMMA IdentifierVal)*)?)? '{' DocumentBody '}' { mixin="ai.vespa.intellij.schema.psi.impl.SdNamedElementImpl" implements=["ai.vespa.intellij.schema.psi.SdDeclaration" "ai.vespa.intellij.schema.psi.SdNamedElement"] } @@ -281,10 +284,10 @@ QueryCommandDefinition ::= query-command ':' (IdentifierVal | STRING_REG | WordW SummaryDefinition ::= summary IdentifierWithDashVal? (type FieldTypeName)? ((':' SummaryBodyOptions) | ( '{' SummaryBody '}')) { mixin="ai.vespa.intellij.schema.psi.impl.SdSummaryDefinitionMixin" } SummaryBody ::= SummaryBodyOptions* // Does not support zero-or-one occurrences -SummaryBodyOptions ::= full | static | dynamic | (source ':' (IdentifierVal ('.' IdentifierVal)?) (',' IdentifierVal ('.' IdentifierVal)?)*) | - (to ':' IdentifierVal (',' IdentifierVal)*) | matched-elements-only | BoldingDefinition +SummaryBodyOptions ::= full | static | dynamic | (source ':' (IdentifierVal ('.' IdentifierVal)?) (COMMA IdentifierVal ('.' IdentifierVal)?)*) | + (to ':' IdentifierVal (COMMA IdentifierVal)*) | matched-elements-only | BoldingDefinition // Summary To -SummaryToDefinition ::= summary-to ':' WordWrapper (',' WordWrapper)* +SummaryToDefinition ::= summary-to ':' WordWrapper (COMMA WordWrapper)* // Bolding BoldingDefinition ::= bolding ':' (on | off | true | false) // Index diff --git a/integration/intellij/src/main/java/ai/vespa/intellij/schema/SdSyntaxHighlighter.java b/integration/intellij/src/main/java/ai/vespa/intellij/schema/SdSyntaxHighlighter.java index 666687e56c1..de0d58c63a0 100644 --- a/integration/intellij/src/main/java/ai/vespa/intellij/schema/SdSyntaxHighlighter.java +++ b/integration/intellij/src/main/java/ai/vespa/intellij/schema/SdSyntaxHighlighter.java @@ -64,7 +64,7 @@ public class SdSyntaxHighlighter extends SyntaxHighlighterBase { return IDENTIFIER_KEYS; } else if (keyWordsSet.contains(tokenType)) { return KEY_KEYS; - } else if (tokenType.equals(SdTypes.SYMBOL)) { + } else if (tokenType.equals(SdTypes.SYMBOL) || tokenType.equals(SdTypes.COMMA)) { return SYMBOL_KEYS; } else if (tokenType.equals(SdTypes.STRING_REG)) { return STRING_KEYS; diff --git a/integration/intellij/src/main/java/ai/vespa/intellij/schema/SdUtil.java b/integration/intellij/src/main/java/ai/vespa/intellij/schema/SdUtil.java index 2bc5fa80e18..c5f9c7fed35 100644 --- a/integration/intellij/src/main/java/ai/vespa/intellij/schema/SdUtil.java +++ b/integration/intellij/src/main/java/ai/vespa/intellij/schema/SdUtil.java @@ -9,8 +9,10 @@ import com.intellij.psi.PsiElement; import com.intellij.psi.PsiManager; import com.intellij.psi.PsiNamedElement; import com.intellij.psi.PsiReference; +import com.intellij.psi.PsiWhiteSpace; import com.intellij.psi.search.FileTypeIndex; import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.psi.tree.IElementType; import com.intellij.psi.util.PsiTreeUtil; import ai.vespa.intellij.schema.psi.SdAnnotationFieldDefinition; import ai.vespa.intellij.schema.psi.SdArgumentDefinition; @@ -62,26 +64,38 @@ public class SdUtil { } /** - * @param baseRankProfile the rank-profile node to find its parent - * @return the rank-profile that the baseRankProfile inherits from, or null if it doesn't exist + * Returns the profiles inherited by this. + * + * @param baseRankProfile the rank-profile node to find the parents of + * @return the profiles this inherits from, empty if none */ public static List<SdRankProfileDefinition> getRankProfileParents(SdRankProfileDefinition baseRankProfile) { - if (baseRankProfile == null) return null; + if (baseRankProfile == null) return List.of(); ASTNode inheritsNode = baseRankProfile.getNode().findChildByType(SdTypes.INHERITS); - if (inheritsNode == null) return null; - - return identifiersIn(inheritsNode).stream() - .map(parentIdentifierAST -> parentIdentifierAST.getPsi().getReference()) - .filter(reference -> reference != null) - .map(reference -> (SdRankProfileDefinition)reference.resolve()) - .collect(Collectors.toList()); + if (inheritsNode == null) return List.of(); + return inherits(baseRankProfile).stream() + .map(parentIdentifierAST -> parentIdentifierAST.getPsi().getReference()) + .filter(reference -> reference != null) + .map(reference -> (SdRankProfileDefinition)reference.resolve()) + .collect(Collectors.toList()); } - private static List<ASTNode> identifiersIn(ASTNode inheritsNode) { - return Arrays.stream(inheritsNode.getChildren(null)) - .filter(node -> node.getElementType() == SdTypes.IDENTIFIER_VAL || - node.getElementType() == SdTypes.IDENTIFIER_WITH_DASH_VAL) - .collect(Collectors.toList()); + private static List<ASTNode> inherits(SdRankProfileDefinition baseRankProfile) { + Tokens tokens = Tokens.of(baseRankProfile); + tokens.require(SdTypes.RANK_PROFILE); + tokens.requireWhitespace(); + tokens.require(SdTypes.IDENTIFIER_VAL, SdTypes.IDENTIFIER_WITH_DASH_VAL); + if ( ! tokens.skipWhitespace()) return List.of(); + if ( ! tokens.skip(SdTypes.INHERITS)) return List.of(); + tokens.requireWhitespace(); + List<ASTNode> inherited = new ArrayList<>(); + do { + inherited.add(tokens.require(SdTypes.IDENTIFIER_VAL, SdTypes.IDENTIFIER_WITH_DASH_VAL)); + tokens.skipWhitespace(); + if ( ! tokens.skip(SdTypes.COMMA)) break; + tokens.skipWhitespace(); + } while (true); + return inherited; } public static String createFunctionDescription(SdFunctionDefinition function) { @@ -237,5 +251,84 @@ public class SdUtil { public static List<PsiElement> findDocumentSummaryChildren(PsiElement element) { return new ArrayList<>(PsiTreeUtil.collectElementsOfType(element, SdSummaryDefinition.class)); } - + + /** A collection of tokens with a current index. */ + public static class Tokens { + + private final ASTNode[] nodes; + private int i = 0; + + private Tokens(PsiElement element) { + nodes = element.getNode().getChildren(null); + } + + /** + * Advances to the next token, if it is of the given type. + * + * @return true if the current token was of the given type and we advanced it, false + * if it was not and nothing was changed + */ + public boolean skip(IElementType ... tokenTypes) { + boolean is = is(tokenTypes); + if (is) + i++; + return is; + } + + /** + * Advances beyond the next token, if it is whitespace. + * + * @return true if the current token was of the given type and we advanced it, false + * if it was not and nothing was changed + */ + public boolean skipWhitespace() { + boolean is = isWhitespace(); + if (is) + i++; + return is; + } + + /** Returns whether the current token is of the given type */ + public boolean is(IElementType ... tokenTypes) { + for (IElementType type : tokenTypes) + if (current().getElementType() == type) return true; + return false; + } + + /** Returns whether the current token is whitespace */ + public boolean isWhitespace() { + return current().getPsi() instanceof PsiWhiteSpace; + } + + /** Returns the current token if it is of the required type and throws otherwise. */ + public ASTNode require(IElementType ... tokenTypes) { + if ( ! is(tokenTypes) ) + throw new IllegalArgumentException("Expected " + toString(tokenTypes) + " but got " + current()); + ASTNode current = current(); + i++; + return current; + } + + public void requireWhitespace() { + if ( ! isWhitespace() ) + throw new IllegalArgumentException("Expected whitespace, but got " + current()); + i++; + } + + /** Returns the current token (AST node), or null if we have reached the end. */ + public ASTNode current() { + if (i >= nodes.length) return null; + return nodes[i]; + } + + private String toString(IElementType[] tokens) { + return Arrays.stream(tokens).map(token -> token.getDebugName()).collect(Collectors.joining(", ")); + } + + public static Tokens of(PsiElement element) { + return new Tokens(element); + } + + } + } diff --git a/integration/intellij/src/main/java/ai/vespa/intellij/schema/model/RankProfile.java b/integration/intellij/src/main/java/ai/vespa/intellij/schema/model/RankProfile.java index fd30a0fbe53..5e927d669dc 100644 --- a/integration/intellij/src/main/java/ai/vespa/intellij/schema/model/RankProfile.java +++ b/integration/intellij/src/main/java/ai/vespa/intellij/schema/model/RankProfile.java @@ -5,6 +5,7 @@ import ai.vespa.intellij.schema.psi.SdFile; import ai.vespa.intellij.schema.psi.SdRankProfileDefinition; import com.intellij.openapi.project.Project; import com.intellij.openapi.vfs.VirtualFile; +import com.intellij.psi.PsiElement; import com.intellij.psi.PsiFile; import com.intellij.psi.PsiManager; import com.intellij.psi.search.FilenameIndex; @@ -34,15 +35,9 @@ public class RankProfile { * @throws IllegalArgumentException if not found */ public static RankProfile fromProjectFile(Project project, String filePath, String profileName) { - PsiFile[] psiFile = FilenameIndex.getFilesByName(project, filePath, GlobalSearchScope.allScope(project)); - if (psiFile.length == 0) - throw new IllegalArgumentException(filePath + " could not be opened"); - if (psiFile.length > 1) - throw new IllegalArgumentException("Multiple files matches " + filePath); - if ( ! (psiFile[0] instanceof SdFile)) - throw new IllegalArgumentException(filePath + " is not a schema or profile"); + PsiElement root = Schema.load(project, filePath); Optional<SdRankProfileDefinition> definition = - PsiTreeUtil.collectElementsOfType(psiFile[0], SdRankProfileDefinition.class) + PsiTreeUtil.collectElementsOfType(root, SdRankProfileDefinition.class) .stream() .filter(p -> p.getName().equals(profileName)) .findAny(); diff --git a/integration/intellij/src/main/java/ai/vespa/intellij/schema/model/Schema.java b/integration/intellij/src/main/java/ai/vespa/intellij/schema/model/Schema.java new file mode 100644 index 00000000000..3b67a5a0290 --- /dev/null +++ b/integration/intellij/src/main/java/ai/vespa/intellij/schema/model/Schema.java @@ -0,0 +1,52 @@ +// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +package ai.vespa.intellij.schema.model; + +import ai.vespa.intellij.schema.psi.SdFile; +import ai.vespa.intellij.schema.psi.SdRankProfileDefinition; +import ai.vespa.intellij.schema.psi.SdSchemaBody; +import ai.vespa.intellij.schema.psi.SdSchemaDefinition; +import com.intellij.openapi.project.Project; +import com.intellij.psi.PsiElement; +import com.intellij.psi.PsiFile; +import com.intellij.psi.search.FilenameIndex; +import com.intellij.psi.search.GlobalSearchScope; +import com.intellij.psi.util.PsiTreeUtil; + +import java.util.Optional; + +/** + * A schema. + * + * @author bratseth + */ +public class Schema { + + private final SdFile definition; + + public Schema(SdFile definition) { + this.definition = definition; + } + + public SdFile definition() { return definition; } + + /** + * Returns the profile of the given name from the given file. + * + * @throws IllegalArgumentException if not found + */ + public static Schema fromProjectFile(Project project, String filePath) { + return new Schema((SdFile)load(project, filePath)); + } + + static PsiElement load(Project project, String filePath) { + PsiFile[] psiFile = FilenameIndex.getFilesByName(project, filePath, GlobalSearchScope.allScope(project)); + if (psiFile.length == 0) + throw new IllegalArgumentException(filePath + " could not be opened"); + if (psiFile.length > 1) + throw new IllegalArgumentException("Multiple files matches " + filePath); + if ( ! (psiFile[0] instanceof SdFile)) + throw new IllegalArgumentException(filePath + " is not a schema file"); + return psiFile[0]; + } + +} diff --git a/integration/intellij/src/main/jflex/ai/vespa/intellij/schema/lexer/sd.flex b/integration/intellij/src/main/jflex/ai/vespa/intellij/schema/lexer/sd.flex index 78334de1961..f3064612b43 100644 --- a/integration/intellij/src/main/jflex/ai/vespa/intellij/schema/lexer/sd.flex +++ b/integration/intellij/src/main/jflex/ai/vespa/intellij/schema/lexer/sd.flex @@ -34,7 +34,10 @@ ID_WITH_DASH = [a-zA-Z_][a-zA-Z0-9_-]* WHITE_SPACE=[ \t\n\x0B\f\r]+ COMMENT=#.* -SYMBOL= [!$|:{}(),.\[\]] +SYMBOL= [!$|:{}().\[\]] +COMMA= [,] +//BLOCK_START= \{ +//BLOCK_END= \} INTEGER = [0-9]+ FLOAT = {INTEGER}[.][0-9]+[e]? COMPARISON_OPERATOR = [<>]|(==)|(<=)|(>=)|(\~=) @@ -217,7 +220,7 @@ WORD = \w+ "evaluation-point" { return EVALUATION_POINT; } "pre-post-filter-tipping-point" { return PRE_POST_FILTER_TIPPING_POINT; } - // In here, we check for character sequences which matches regular expressions defined above. + // Here we check for character sequences which matches regular expressions defined above. {ID} { return ID_REG; } {ID_WITH_DASH} { return ID_WITH_DASH_REG; } @@ -225,6 +228,9 @@ WORD = \w+ {COMMENT} { return COMMENT; } {SYMBOL} { return SYMBOL; } + {COMMA} { return COMMA; } + //{BLOCK_START} { return BLOCK_START; } + //{BLOCK_END} { return BLOCK_END; } {INTEGER} { return INTEGER_REG; } {FLOAT} { return FLOAT_REG; } {ARITHMETIC_OPERATOR} { return ARITHMETIC_OPERATOR; } diff --git a/integration/intellij/src/test/applications/schemainheritance/child.sd b/integration/intellij/src/test/applications/schemainheritance/child.sd index a209919763d..e45f5cb3991 100644 --- a/integration/intellij/src/test/applications/schemainheritance/child.sd +++ b/integration/intellij/src/test/applications/schemainheritance/child.sd @@ -22,7 +22,10 @@ schema child inherits parent { indexing: input pf1 | lowercase | index | attribute | summary } - rank-profile child_profile inherits parent_profile { + rank-profile child_profile inherits other_child_profile, parent_profile { + } + + rank-profile other_child_profile { } constant child_constant { diff --git a/integration/intellij/src/test/applications/simple/simple.sd b/integration/intellij/src/test/applications/simple/simple.sd new file mode 100644 index 00000000000..21e683b3ee4 --- /dev/null +++ b/integration/intellij/src/test/applications/simple/simple.sd @@ -0,0 +1,15 @@ +schema simple { + + document simple { + } + + rank-profile simple-profile inherits parent-profile1, parent-profile2 { + } + + rank-profile parent-profile1 { + } + + rank-profile parent-profile2 { + } + +}
\ No newline at end of file diff --git a/integration/intellij/src/test/java/ai/vespa/intellij/model/MockProject.java b/integration/intellij/src/test/java/ai/vespa/intellij/model/MockProject.java deleted file mode 100644 index f54dfdee2ef..00000000000 --- a/integration/intellij/src/test/java/ai/vespa/intellij/model/MockProject.java +++ /dev/null @@ -1,147 +0,0 @@ -// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package ai.vespa.intellij.model; - -import com.intellij.diagnostic.ActivityCategory; -import com.intellij.openapi.extensions.PluginDescriptor; -import com.intellij.openapi.extensions.PluginId; -import com.intellij.openapi.project.Project; -import com.intellij.openapi.util.Condition; -import com.intellij.openapi.util.Key; -import com.intellij.openapi.vfs.VirtualFile; -import com.intellij.util.messages.MessageBus; -import org.picocontainer.PicoContainer; - -import java.io.File; -import java.util.Map; - -public class MockProject implements Project { - - private final File schemasDir; - - public MockProject(File schemasDir) { - this.schemasDir = schemasDir; - } - - @Override - public String getName() { return "mock project"; } - - @Override - public VirtualFile getBaseDir() { - throw new UnsupportedOperationException(); - } - - @Override - public String getBasePath() { - throw new UnsupportedOperationException(); - } - - @Override - public VirtualFile getProjectFile() { - throw new UnsupportedOperationException(); - } - - @Override - public String getProjectFilePath() { - throw new UnsupportedOperationException(); - } - - @Override - public VirtualFile getWorkspaceFile() { - throw new UnsupportedOperationException(); - } - - @Override - public String getLocationHash() { - throw new UnsupportedOperationException(); - } - - @Override - public void save() { - throw new UnsupportedOperationException(); - } - - @Override - public boolean isOpen() { return true; } - - @Override - public boolean isInitialized() { return true; } - - @Override - public <T> T getComponent(Class<T> interfaceClass) { - throw new UnsupportedOperationException(); - } - - @Override - public <T> T[] getComponents(Class<T> baseClass) { - throw new UnsupportedOperationException(); - } - - @Override - public PicoContainer getPicoContainer() { - throw new UnsupportedOperationException(); - } - - @Override - public boolean isInjectionForExtensionSupported() { return false; } - - @Override - public MessageBus getMessageBus() { - throw new UnsupportedOperationException(); - } - - @Override - public boolean isDisposed() { return false; } - - @Override - public Condition<?> getDisposed() { - throw new UnsupportedOperationException(); - } - - @Override - public <T> T getService(Class<T> serviceClass) { - throw new UnsupportedOperationException(); - } - - @Override - public <T> T instantiateClassWithConstructorInjection(Class<T> aClass, Object key, PluginId pluginId) { - throw new UnsupportedOperationException(); - } - - @Override - public RuntimeException createError(Throwable error, PluginId pluginId) { - throw new UnsupportedOperationException(); - } - - @Override - public RuntimeException createError(String message, PluginId pluginId) { - throw new UnsupportedOperationException(); - } - - @Override - public RuntimeException createError(String message, Throwable error, PluginId pluginId, Map<String, String> attachments) { - throw new UnsupportedOperationException(); - } - - @Override - public <T> Class<T> loadClass(String className, PluginDescriptor pluginDescriptor) throws ClassNotFoundException { - throw new UnsupportedOperationException(); - } - - @Override - public ActivityCategory getActivityCategory(boolean isExtension) { - throw new UnsupportedOperationException(); - } - - @Override - public void dispose() { - } - - @Override - public <T> T getUserData(Key<T> key) { return null; } - - @Override - public <T> void putUserData(Key<T> key, T value) { - throw new UnsupportedOperationException(); - } - -} diff --git a/integration/intellij/src/test/java/ai/vespa/intellij/model/RankProfileTest.java b/integration/intellij/src/test/java/ai/vespa/intellij/model/RankProfileTest.java deleted file mode 100644 index c0b4902c002..00000000000 --- a/integration/intellij/src/test/java/ai/vespa/intellij/model/RankProfileTest.java +++ /dev/null @@ -1,32 +0,0 @@ -// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. -package ai.vespa.intellij.model; - -import ai.vespa.intellij.schema.model.RankProfile; -import com.intellij.testFramework.LightProjectDescriptor; -import com.intellij.testFramework.fixtures.LightJavaCodeInsightFixtureTestCase; -import org.junit.Test; - -import java.io.File; - -/** - * @author bratseth - */ -public class RankProfileTest extends LightJavaCodeInsightFixtureTestCase { - - @Override - protected LightProjectDescriptor getProjectDescriptor() { - // Store the descriptor between tests to make this faster - return new TestProjectDescriptor(); - } - - @Override - protected String getTestDataPath() { return "."; } - - @Test - public void testFindDefinition() { - super.myFixture.copyDirectoryToProject("src/test/applications/schemainheritance", "/"); - RankProfile profile = RankProfile.fromProjectFile(getProject(), "child.sd", "child_profile"); - assertEquals("child_profile", profile.definition().getName()); - } - -} diff --git a/integration/intellij/src/test/java/ai/vespa/intellij/model/SchemaTest.java b/integration/intellij/src/test/java/ai/vespa/intellij/model/SchemaTest.java new file mode 100644 index 00000000000..38fd9a97a5b --- /dev/null +++ b/integration/intellij/src/test/java/ai/vespa/intellij/model/SchemaTest.java @@ -0,0 +1,59 @@ +// Copyright Yahoo. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. +package ai.vespa.intellij.model; + +import ai.vespa.intellij.schema.SdUtil; +import ai.vespa.intellij.schema.model.RankProfile; +import ai.vespa.intellij.schema.model.Schema; +import ai.vespa.intellij.schema.psi.SdRankProfileDefinition; +import com.intellij.testFramework.LightProjectDescriptor; +import com.intellij.testFramework.fixtures.LightJavaCodeInsightFixtureTestCase; +import org.junit.Test; + +import java.util.List; + +/** + * @author bratseth + */ +public class SchemaTest extends LightJavaCodeInsightFixtureTestCase { + + private final TestProjectDescriptor descriptor; + + public SchemaTest() { + descriptor = new TestProjectDescriptor(); // Expensive instance + } + + @Override + protected LightProjectDescriptor getProjectDescriptor() { return descriptor; } + + @Override + protected String getTestDataPath() { return "."; } + + @Test + public void testSimple() { + super.myFixture.copyDirectoryToProject("src/test/applications/simple", "/"); + Schema schema = Schema.fromProjectFile(getProject(), "simple.sd"); + assertNotNull(schema); + assertEquals("simple.sd", schema.definition().getName()); + RankProfile profile = RankProfile.fromProjectFile(getProject(), "simple.sd", "simple-profile"); + assertEquals("simple-profile", profile.definition().getName()); + List<SdRankProfileDefinition> parents = SdUtil.getRankProfileParents(profile.definition()); + assertEquals(2, parents.size()); + assertEquals("parent-profile1", parents.get(0).getName()); + assertEquals("parent-profile2", parents.get(1).getName()); + } + + @Test + public void testSchemaInheritance() { + super.myFixture.copyDirectoryToProject("src/test/applications/schemainheritance", "/"); + Schema schema = Schema.fromProjectFile(getProject(), "child.sd"); + assertNotNull(schema); + assertEquals("child.sd", schema.definition().getName()); + RankProfile profile = RankProfile.fromProjectFile(getProject(), "child.sd", "child_profile"); + assertEquals("child_profile", profile.definition().getName()); + List<SdRankProfileDefinition> parents = SdUtil.getRankProfileParents(profile.definition()); + assertEquals(2, parents.size()); + assertEquals("other_child_profile", parents.get(0).getName()); + // assertEquals("parent-profile", parents.get(1).getName()); TODO + } + +} diff --git a/integration/intellij/src/test/java/ai/vespa/intellij/model/TestProjectDescriptor.java b/integration/intellij/src/test/java/ai/vespa/intellij/model/TestProjectDescriptor.java index ae36c16ce67..5952b17a642 100644 --- a/integration/intellij/src/test/java/ai/vespa/intellij/model/TestProjectDescriptor.java +++ b/integration/intellij/src/test/java/ai/vespa/intellij/model/TestProjectDescriptor.java @@ -3,8 +3,6 @@ package ai.vespa.intellij.model; import com.intellij.testFramework.LightProjectDescriptor; -import java.io.File; - /** * Describes a project used in unit tests. * https://plugins.jetbrains.com/docs/intellij/light-and-heavy-tests.html @@ -12,5 +10,5 @@ import java.io.File; * @author bratseth */ public class TestProjectDescriptor extends LightProjectDescriptor { - + } |