/* * 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.project.build.validation; import static org.assertj.core.api.Assertions.assertThat; import java.util.List; import java.util.Optional; import org.eclipse.core.runtime.CoreException; import org.junit.Before; import org.junit.Test; import org.rf.ide.core.testdata.model.table.RobotExecutableRow; import org.rf.ide.core.testdata.model.table.exec.descs.IExecutableRowDescriptor; import org.rf.ide.core.testdata.model.table.testcases.TestCase; import org.rf.ide.core.testdata.text.read.recognizer.RobotToken; import org.rf.ide.core.validation.ProblemPosition; import org.robotframework.ide.eclipse.main.plugin.mockmodel.RobotSuiteFileCreator; import org.robotframework.ide.eclipse.main.plugin.model.RobotCase; import org.robotframework.ide.eclipse.main.plugin.model.RobotCasesSection; import org.robotframework.ide.eclipse.main.plugin.model.RobotSuiteFile; import org.robotframework.ide.eclipse.main.plugin.project.build.causes.ArgumentProblem; import org.robotframework.ide.eclipse.main.plugin.project.build.validation.MockReporter.Problem; import org.robotframework.ide.eclipse.main.plugin.project.library.ArgumentsDescriptor; import com.google.common.collect.Range; public class KeywordCallArgumentsValidatorTest { private MockReporter reporter; @Before public void beforeTest() { reporter = new MockReporter(); } @Test public void nothingIsReported_whenThereIsExactNumberOfArguments() throws CoreException { final RobotSuiteFile file = new RobotSuiteFileCreator() .appendLine("*** Test Cases ***") .appendLine("test") .appendLine(" keyword arg") .build(); final DefiningTokenWithArgumentTokens tokens = getKeywordCallTokensFromFirstLineOf(file, "test"); final ArgumentsDescriptor descriptor = ArgumentsDescriptor.createDescriptor("x"); validate(file, tokens, descriptor); assertThat(reporter.getNumberOfReportedProblems()).isEqualTo(0); } @Test public void invalidNumberOfParametersIsReported_whenThereAreToFewArguments() throws CoreException { final RobotSuiteFile file = new RobotSuiteFileCreator() .appendLine("*** Test Cases ***") .appendLine("test") .appendLine(" keyword") .build(); final DefiningTokenWithArgumentTokens tokens = getKeywordCallTokensFromFirstLineOf(file, "test"); final ArgumentsDescriptor descriptor = ArgumentsDescriptor.createDescriptor("x"); validate(file, tokens, descriptor); assertThat(reporter.getNumberOfReportedProblems()).isEqualTo(1); assertThat(reporter.getReportedProblems()).containsExactly(new Problem( ArgumentProblem.INVALID_NUMBER_OF_PARAMETERS, new ProblemPosition(3, Range.closed(28, 35)))); } @Test public void invalidNumberOfParametersIsReported_whenThereAreTooManyArguments() throws CoreException { final RobotSuiteFile file = new RobotSuiteFileCreator() .appendLine("*** Test Cases ***") .appendLine("test") .appendLine(" keyword arg1 arg2") .build(); final DefiningTokenWithArgumentTokens tokens = getKeywordCallTokensFromFirstLineOf(file, "test"); final ArgumentsDescriptor descriptor = ArgumentsDescriptor.createDescriptor("x"); validate(file, tokens, descriptor); assertThat(reporter.getNumberOfReportedProblems()).isEqualTo(1); assertThat(reporter.getReportedProblems()).containsExactly(new Problem( ArgumentProblem.INVALID_NUMBER_OF_PARAMETERS, new ProblemPosition(3, Range.closed(28, 35)))); } @Test public void nothingIsReported_whenNumberOfArgumentsAreInBoundedRange() throws CoreException { final RobotSuiteFile file = new RobotSuiteFileCreator() .appendLine("*** Test Cases ***") .appendLine("test") .appendLine(" keyword arg1 arg2") .build(); final DefiningTokenWithArgumentTokens tokens = getKeywordCallTokensFromFirstLineOf(file, "test"); final ArgumentsDescriptor descriptor = ArgumentsDescriptor.createDescriptor("x", "y=1", "z=2"); validate(file, tokens, descriptor); assertThat(reporter.getNumberOfReportedProblems()).isEqualTo(0); } @Test public void invalidNumberOfParametersIsReported_whenThereAreToFewArgumentsThanInBoundedRange() throws CoreException { final RobotSuiteFile file = new RobotSuiteFileCreator() .appendLine("*** Test Cases ***") .appendLine("test") .appendLine(" keyword") .build(); final DefiningTokenWithArgumentTokens tokens = getKeywordCallTokensFromFirstLineOf(file, "test"); final ArgumentsDescriptor descriptor = ArgumentsDescriptor.createDescriptor("x", "y=1", "z=2"); validate(file, tokens, descriptor); assertThat(reporter.getNumberOfReportedProblems()).isEqualTo(1); assertThat(reporter.getReportedProblems()).containsExactly(new Problem( ArgumentProblem.INVALID_NUMBER_OF_PARAMETERS, new ProblemPosition(3, Range.closed(28, 35)))); } @Test public void invalidNumberOfParametersIsReported_whenThereAreTooManyArgumentsThanInBoundedRange() throws CoreException { final RobotSuiteFile file = new RobotSuiteFileCreator() .appendLine("*** Test Cases ***") .appendLine("test") .appendLine(" keyword arg1 arg2 arg3 arg4") .build(); final DefiningTokenWithArgumentTokens tokens = getKeywordCallTokensFromFirstLineOf(file, "test"); final ArgumentsDescriptor descriptor = ArgumentsDescriptor.createDescriptor("x", "y=1", "z=2"); validate(file, tokens, descriptor); assertThat(reporter.getNumberOfReportedProblems()).isEqualTo(1); assertThat(reporter.getReportedProblems()).containsExactly(new Problem( ArgumentProblem.INVALID_NUMBER_OF_PARAMETERS, new ProblemPosition(3, Range.closed(28, 35)))); } @Test public void nothingIsReported_whenNumberOfArgumentsAreInUnoundedRange() throws CoreException { final RobotSuiteFile file = new RobotSuiteFileCreator() .appendLine("*** Test Cases ***") .appendLine("test") .appendLine(" keyword arg1 arg2 arg3") .build(); final DefiningTokenWithArgumentTokens tokens = getKeywordCallTokensFromFirstLineOf(file, "test"); final ArgumentsDescriptor descriptor = ArgumentsDescriptor.createDescriptor("x", "y", "*z"); validate(file, tokens, descriptor); assertThat(reporter.getNumberOfReportedProblems()).isEqualTo(0); } @Test public void invalidNumberOfParametersIsReported_whenThereAreToFewArgumentsThanInUnboundedRange() throws CoreException { final RobotSuiteFile file = new RobotSuiteFileCreator() .appendLine("*** Test Cases ***") .appendLine("test") .appendLine(" keyword arg") .build(); final DefiningTokenWithArgumentTokens tokens = getKeywordCallTokensFromFirstLineOf(file, "test"); final ArgumentsDescriptor descriptor = ArgumentsDescriptor.createDescriptor("x", "y", "*z"); validate(file, tokens, descriptor); assertThat(reporter.getNumberOfReportedProblems()).isEqualTo(1); assertThat(reporter.getReportedProblems()).containsExactly(new Problem( ArgumentProblem.INVALID_NUMBER_OF_PARAMETERS, new ProblemPosition(3, Range.closed(28, 35)))); } @Test public void positionalArgumentsAreReported_whenTheyAreUsedAfterNamedOnes_1() { final RobotSuiteFile file = new RobotSuiteFileCreator() .appendLine("*** Test Cases ***") .appendLine("test") .appendLine(" keyword x=5 arg z=10") .build(); final DefiningTokenWithArgumentTokens tokens = getKeywordCallTokensFromFirstLineOf(file, "test"); final ArgumentsDescriptor descriptor = ArgumentsDescriptor.createDescriptor("x", "y", "z"); validate(file, tokens, descriptor); assertThat(reporter.getNumberOfReportedProblems()).isEqualTo(1); assertThat(reporter.getReportedProblems()).containsExactly( new Problem(ArgumentProblem.POSITIONAL_ARGUMENT_AFTER_NAMED, new ProblemPosition(3, Range.closed(46, 49)))); } @Test public void positionalArgumentsAreReported_whenTheyAreUsedAfterNamedOnes_2() { final RobotSuiteFile file = new RobotSuiteFileCreator() .appendLine("*** Test Cases ***") .appendLine("test") .appendLine(" keyword x=5 arg w=10") .build(); final DefiningTokenWithArgumentTokens tokens = getKeywordCallTokensFromFirstLineOf(file, "test"); final ArgumentsDescriptor descriptor = ArgumentsDescriptor.createDescriptor("x", "y", "z"); validate(file, tokens, descriptor); assertThat(reporter.getNumberOfReportedProblems()).isEqualTo(2); assertThat(reporter.getReportedProblems()).containsExactly( new Problem(ArgumentProblem.POSITIONAL_ARGUMENT_AFTER_NAMED, new ProblemPosition(3, Range.closed(46, 49))), new Problem(ArgumentProblem.POSITIONAL_ARGUMENT_AFTER_NAMED, new ProblemPosition(3, Range.closed(53, 57)))); } @Test public void namedArgumentIsReported_whenItMatchesArgumentAlreadyDefinedByPositionalOne() { final RobotSuiteFile file = new RobotSuiteFileCreator() .appendLine("*** Test Cases ***") .appendLine("test") .appendLine(" keyword 1 x=2") .build(); final DefiningTokenWithArgumentTokens tokens = getKeywordCallTokensFromFirstLineOf(file, "test"); final ArgumentsDescriptor descriptor = ArgumentsDescriptor.createDescriptor("x", "y=0"); validate(file, tokens, descriptor); assertThat(reporter.getNumberOfReportedProblems()).isEqualTo(1); assertThat(reporter.getReportedProblems()).containsExactly(new Problem( ArgumentProblem.MULTIPLE_MATCH_TO_SINGLE_ARG, new ProblemPosition(3, Range.closed(44, 47)))); } @Test public void namedArgumentIsReported_whenItMatchesArgumentAlreadyDefinedByOtherNamedOne() { final RobotSuiteFile file = new RobotSuiteFileCreator() .appendLine("*** Test Cases ***") .appendLine("test") .appendLine(" keyword 1 y=2 y=3") .build(); final DefiningTokenWithArgumentTokens tokens = getKeywordCallTokensFromFirstLineOf(file, "test"); final ArgumentsDescriptor descriptor = ArgumentsDescriptor.createDescriptor("x", "y=0", "z=0"); validate(file, tokens, descriptor); assertThat(reporter.getNumberOfReportedProblems()).isEqualTo(1); assertThat(reporter.getReportedProblems()).containsExactly(new Problem( ArgumentProblem.MULTIPLE_MATCH_TO_SINGLE_ARG, new ProblemPosition(3, Range.closed(51, 54)))); } @Test public void namedArgumentIsReported_whenItMatchesArgumentAlreadyDefinedByOtherNamedOneInPresenceOfKwargs() { final RobotSuiteFile file = new RobotSuiteFileCreator() .appendLine("*** Test Cases ***") .appendLine("test") .appendLine(" keyword 1 arg=2 y=3 z=4") .build(); final DefiningTokenWithArgumentTokens tokens = getKeywordCallTokensFromFirstLineOf(file, "test"); final ArgumentsDescriptor descriptor = ArgumentsDescriptor.createDescriptor("arg", "**kwargs"); validate(file, tokens, descriptor); assertThat(reporter.getNumberOfReportedProblems()).isEqualTo(1); assertThat(reporter.getReportedProblems()).containsExactly(new Problem( ArgumentProblem.MULTIPLE_MATCH_TO_SINGLE_ARG, new ProblemPosition(3, Range.closed(43, 48)))); } @Test public void missingRequiredArgumentIsReported_whenThereIsNoValueProvidedForIt() { final RobotSuiteFile file = new RobotSuiteFileCreator() .appendLine("*** Test Cases ***") .appendLine("test") .appendLine(" keyword y=2") .build(); final DefiningTokenWithArgumentTokens tokens = getKeywordCallTokensFromFirstLineOf(file, "test"); final ArgumentsDescriptor descriptor = ArgumentsDescriptor.createDescriptor("x", "y=0"); validate(file, tokens, descriptor); assertThat(reporter.getNumberOfReportedProblems()).isEqualTo(1); assertThat(reporter.getReportedProblems()).containsExactly(new Problem( ArgumentProblem.NO_VALUE_PROVIDED_FOR_REQUIRED_ARG, new ProblemPosition(3, Range.closed(28, 35)))); } @Test public void nothingIsReported_whenKeywordWithVarargIsCalledWithMultipleArguments() { final RobotSuiteFile file = new RobotSuiteFileCreator() .appendLine("*** Test Cases ***") .appendLine("test") .appendLine(" keyword 1 2 3 4 5") .build(); final DefiningTokenWithArgumentTokens tokens = getKeywordCallTokensFromFirstLineOf(file, "test"); final ArgumentsDescriptor descriptor = ArgumentsDescriptor.createDescriptor("arg", "*args"); validate(file, tokens, descriptor); assertThat(reporter.getReportedProblems()).isEmpty(); } @Test public void nothingIsReported_whenKeywordWithKwargsIsCalledWithMultipleArguments() { final RobotSuiteFile file = new RobotSuiteFileCreator() .appendLine("*** Test Cases ***") .appendLine("test") .appendLine(" keyword 1 a=2 b=3") .build(); final DefiningTokenWithArgumentTokens tokens = getKeywordCallTokensFromFirstLineOf(file, "test"); final ArgumentsDescriptor descriptor = ArgumentsDescriptor.createDescriptor("arg", "**kwargs"); validate(file, tokens, descriptor); assertThat(reporter.getReportedProblems()).isEmpty(); } @Test public void nothingIsReported_whenDictionaryIsUsedWithNamedArguments() { final RobotSuiteFile file = new RobotSuiteFileCreator() .appendLine("*** Test Cases ***") .appendLine("test") .appendLine(" keyword 1 a=2 &{d} b=3") .build(); final DefiningTokenWithArgumentTokens tokens = getKeywordCallTokensFromFirstLineOf(file, "test"); final ArgumentsDescriptor descriptor = ArgumentsDescriptor.createDescriptor("arg", "**kwargs"); validate(file, tokens, descriptor); assertThat(reporter.getReportedProblems()).isEmpty(); } @Test public void positionalArgumentsAreReported_whenTheyWereMatchedToKwargsArgument() { final RobotSuiteFile file = new RobotSuiteFileCreator() .appendLine("*** Test Cases ***") .appendLine("test") .appendLine(" keyword 1 2 3") .build(); final DefiningTokenWithArgumentTokens tokens = getKeywordCallTokensFromFirstLineOf(file, "test"); final ArgumentsDescriptor descriptor = ArgumentsDescriptor.createDescriptor("arg", "**kwargs"); validate(file, tokens, descriptor); assertThat(reporter.getNumberOfReportedProblems()).isEqualTo(2); assertThat(reporter.getReportedProblems()).containsExactly( new Problem(ArgumentProblem.MISMATCHING_ARGUMENT, new ProblemPosition(3, Range.closed(43, 44))), new Problem(ArgumentProblem.MISMATCHING_ARGUMENT, new ProblemPosition(3, Range.closed(47, 48)))); } @Test public void warningIsReported_whenListIsUsedInOrderToProvideMultipleArguments() { final RobotSuiteFile file = new RobotSuiteFileCreator() .appendLine("*** Test Cases ***") .appendLine("test") .appendLine(" keyword @{variables}") .build(); final DefiningTokenWithArgumentTokens tokens = getKeywordCallTokensFromFirstLineOf(file, "test"); final ArgumentsDescriptor descriptor = ArgumentsDescriptor.createDescriptor("x", "y"); validate(file, tokens, descriptor); assertThat(reporter.getNumberOfReportedProblems()).isEqualTo(1); assertThat(reporter.getReportedProblems()).containsExactly(new Problem( ArgumentProblem.LIST_ARGUMENT_SHOULD_PROVIDE_ARGS, new ProblemPosition(3, Range.closed(39, 51)))); } @Test public void warningIsReported_whenDictionaryIsUsedInOrderToProvideMultipleArguments() { final RobotSuiteFile file = new RobotSuiteFileCreator() .appendLine("*** Test Cases ***") .appendLine("test") .appendLine(" keyword &{variables}") .build(); final DefiningTokenWithArgumentTokens tokens = getKeywordCallTokensFromFirstLineOf(file, "test"); final ArgumentsDescriptor descriptor = ArgumentsDescriptor.createDescriptor("x", "y"); validate(file, tokens, descriptor); assertThat(reporter.getNumberOfReportedProblems()).isEqualTo(1); assertThat(reporter.getReportedProblems()).containsExactly(new Problem( ArgumentProblem.DICT_ARGUMENT_SHOULD_PROVIDE_ARGS, new ProblemPosition(3, Range.closed(39, 51)))); } @Test public void warningIsReported_whenListIsUsedInOrderToProvideMultipleArguments_2() { final RobotSuiteFile file = new RobotSuiteFileCreator() .appendLine("*** Test Cases ***") .appendLine("test") .appendLine(" ${a}= keyword @{variables}") .build(); final DefiningTokenWithArgumentTokens tokens = getKeywordCallTokensFromFirstLineOf(file, "test"); final ArgumentsDescriptor descriptor = ArgumentsDescriptor.createDescriptor("x", "y"); validate(file, tokens, descriptor); assertThat(reporter.getNumberOfReportedProblems()).isEqualTo(1); assertThat(reporter.getReportedProblems()).containsExactly(new Problem( ArgumentProblem.LIST_ARGUMENT_SHOULD_PROVIDE_ARGS, new ProblemPosition(3, Range.closed(48, 60)))); } @Test public void nothingIsReported_whenSomethingWhichSeemToBeAListIsUsed() { final RobotSuiteFile file = new RobotSuiteFileCreator() .appendLine("*** Test Cases ***") .appendLine("test") .appendLine(" keyword @{b") .build(); final DefiningTokenWithArgumentTokens tokens = getKeywordCallTokensFromFirstLineOf(file, "test"); final ArgumentsDescriptor descriptor = ArgumentsDescriptor.createDescriptor("x"); validate(file, tokens, descriptor); assertThat(reporter.getReportedProblems()).isEmpty(); } @Test public void nothingIsReported_whenSomethingWhichSeemToBeADictionaryIsUsed() { final RobotSuiteFile file = new RobotSuiteFileCreator() .appendLine("*** Test Cases ***") .appendLine("test") .appendLine(" keyword &{b") .build(); final DefiningTokenWithArgumentTokens tokens = getKeywordCallTokensFromFirstLineOf(file, "test"); final ArgumentsDescriptor descriptor = ArgumentsDescriptor.createDescriptor("x"); validate(file, tokens, descriptor); assertThat(reporter.getReportedProblems()).isEmpty(); } private void validate(final RobotSuiteFile file, final DefiningTokenWithArgumentTokens tokens, final ArgumentsDescriptor descriptor) { final KeywordCallArgumentsValidator validator = new KeywordCallArgumentsValidator(file.getFile(), tokens.definingToken, reporter, descriptor, tokens.argumentTokens); validator.validate(null); } private static DefiningTokenWithArgumentTokens getKeywordCallTokensFromFirstLineOf(final RobotSuiteFile file, final String caseName) { final Optional<RobotCasesSection> casesSection = file.findSection(RobotCasesSection.class); final RobotCase testCase = (RobotCase) casesSection.get().findChild(caseName); final RobotExecutableRow<TestCase> executable = testCase.getLinkedElement().getTestExecutionRows().get(0); final IExecutableRowDescriptor<?> executableRowDescriptor = executable.buildLineDescription(); return new DefiningTokenWithArgumentTokens(executableRowDescriptor.getAction().getToken(), executableRowDescriptor.getKeywordArguments()); } private static class DefiningTokenWithArgumentTokens { RobotToken definingToken; List<RobotToken> argumentTokens; DefiningTokenWithArgumentTokens(final RobotToken definingToken, final List<RobotToken> arguments) { this.definingToken = definingToken; this.argumentTokens = arguments; } } }