rlogiacco / Natural

Natural is a collection of Eclipse plugins to enable rich smart editing of acceptance tests using natural language definition files. It currently supports Cucumber and JBehave syntax.
Eclipse Public License 1.0
75 stars 37 forks source link

Editing .feature file causes "Error executing EValidator" in latest veresion of Eclipse #87

Open mikeauen opened 4 years ago

mikeauen commented 4 years ago

When using the latest Natural plugin in the latest Eclipse to edit feature files, an error is immediately thrown in the file "Error executing EValidator". Not only is the error shown, but it also seems to prevent ctrl+click on the steps linking to the step files. Every developer on my team sees this same problem, but I cannot find anyone else complaining about this when doing google searches. Could this be a bug in the plugin, or is there a known way to address this in Eclipse?

rlogiacco commented 4 years ago

Please provide exact version of Eclipse, JVM and Natural plugin in use along with anything else you might consider relevant for diagnosing.

mikeauen commented 4 years ago

Hi, thank you for replying.

Eclipse: Eclipse IDE for Java Developers (includes Incubating components) Version: 2020-06 (4.16.0) Build id: 20200615-1200

Natural: org.agileware.natural.cucumber.feature.feature.group Version 0.7.7.202005221158

Java: java version "1.8.0_261" Java(TM) SE Runtime Environment (build 1.8.0_261-b12) Java HotSpot(TM) 64-Bit Server VM (build 25.261-b12, mixed mode)

As far as other details for diagnosing, I am not sure what useful info I can provide. I recreated it just now by installing Natural and restarting Eclipse. I opened a .feature file, and made a simple edit (add a carriage return at the end of the file). The error immediately pops up on the file. I am also unable to ctrl+click on the steps to go to the linked Step file, and if I modify a step to some invalid value, there is no indication that the step definition does not exist.

Between myself and my team members, this is happening consistently on Windows 10 machines, Windows 10 VMs, and Linux VMs.

image

miklossy commented 4 years ago

@mikeauen It could be also interesting which Xtext version you use.

mikeauen commented 4 years ago

@miklossy , Here is the XText info:

org.eclipse.xtext (2.22.0.v20200602-1352) "Xtext" [Active] org.eclipse.xtext.builder (2.22.0.v20200602-1242) "Xtext Builder" [Active] org.eclipse.xtext.common.types (2.22.0.v20200602-1114) "Xtext Common Types" [Active] org.eclipse.xtext.common.types.edit (2.22.0.v20200602-1242) "Xtext Common Types Edit" [Resolved] org.eclipse.xtext.common.types.ui (2.22.0.v20200602-1242) "Xtext Common Types UI" [Resolved] org.eclipse.xtext.ecore (2.22.0.v20200602-1114) "Xtext Ecore Support" [Starting] org.eclipse.xtext.generator (2.22.0.v20200602-1114) "Xtext Generator" [Starting] org.eclipse.xtext.ide (2.22.0.v20200602-1352) "Xtext IDE Core" [Active] org.eclipse.xtext.smap (2.22.0.v20200602-1114) "Xtext JSR-45 SMAP installer" [Resolved] org.eclipse.xtext.ui (2.22.0.v20200602-1242) "Xtext UI Core " [Active] org.eclipse.xtext.ui.codetemplates (2.22.0.v20200602-1242) "Xtext Codetemplates Language Runtime" [Starting] org.eclipse.xtext.ui.codetemplates.ide (2.22.0.v20200602-1242) "Xtext Codetemplates Language Generic Ide" [Resolved] org.eclipse.xtext.ui.codetemplates.ui (2.22.0.v20200602-1242) "Xtext Codetemplates Language UI" [Active] org.eclipse.xtext.ui.shared (2.22.0.v20200602-1242) "Xtext UI Shared" [Active] org.eclipse.xtext.util (2.22.0.v20200602-1352) "Xtext Utility" [Resolved] org.eclipse.xtext.xbase (2.22.0.v20200602-1114) "Xbase Model" [Starting] org.eclipse.xtext.xbase.lib (2.22.0.v20200602-0713) "Xbase Runtime Library" [Resolved] org.eclipse.xtext.xtext.generator (2.22.0.v20200602-1352) "Xtext Generator 2" [Starting]

miklossy commented 4 years ago

Thanks! Do you see any entries in the Error View?

mikeauen commented 4 years ago

@miklossy This is interesting. Yesterday I was seeing errors (Xtext related) in the Problems log. But now that I have reinstalled the plugin those are not showing up. Also, the files would show red error X's in the package explorer view on the left hand side. Today they are not. Unfortunately, I do not have a screenshot of the errors that were shown yesterday. Also to note, When I have the Error view open, nothing shows up there when the error appears.

image

miklossy commented 4 years ago

I mean the Error view, not the Problem view.

mikeauen commented 4 years ago

@miklossy The Error view is not showing anything today when the error occurs. I do not recall if it was yesterday.

miklossy commented 4 years ago

And how about the Eclipse Log file? https://javapapers.com/tips/eclipse-log-file-location/

mikeauen commented 4 years ago

@miklossy This is interesting. I see some errors in the log related to the string variables in the step definitions. Does Natural plugin require the string definitions in the step definitions to use regex for the strings (ie. "I navigate to {string} in the left hand menu" vs. something like "I navigate to "[^\"]*" in the left hand menu"... apologies if my regex example is wrong, it has been a while since I used it). I see entries like this in the attached error log:

log.txt

!ENTRY org.eclipse.ui 4 0 2020-08-21 18:55:38.391
!MESSAGE Unhandled event loop exception
!STACK 0
java.util.regex.PatternSyntaxException: Illegal repetition near index 15
I navigate to {string} in the left hand menu
               ^
    at java.base/java.util.regex.Pattern.error(Pattern.java:2027)
    at java.base/java.util.regex.Pattern.closure(Pattern.java:3326)
    at java.base/java.util.regex.Pattern.sequence(Pattern.java:2213)
    at java.base/java.util.regex.Pattern.expr(Pattern.java:2068)
    at java.base/java.util.regex.Pattern.compile(Pattern.java:1782)
    at java.base/java.util.regex.Pattern.<init>(Pattern.java:1429)
    at java.base/java.util.regex.Pattern.compile(Pattern.java:1069)
    at java.base/java.util.regex.Pattern.matches(Pattern.java:1174)
    at java.base/java.lang.String.matches(String.java:2046)
    at org.agileware.natural.common.JavaAnnotationMatcher.findMatches(JavaAnnotationMatcher.java:71)
    at org.agileware.natural.cucumber.ui.CucumberHyperlinkHelper.findLinkTargets(CucumberHyperlinkHelper.java:54)
    at org.agileware.natural.cucumber.ui.CucumberHyperlinkHelper.createHyperlinksByOffset(CucumberHyperlinkHelper.java:47)
    at org.eclipse.xtext.ui.editor.hyperlinking.DefaultHyperlinkDetector$1.exec(DefaultHyperlinkDetector.java:52)
    at org.eclipse.xtext.ui.editor.hyperlinking.DefaultHyperlinkDetector$1.exec(DefaultHyperlinkDetector.java:1)
    at org.eclipse.xtext.util.concurrent.IReadAccess.lambda$tryReadOnly$0(IReadAccess.java:57)
    at org.eclipse.xtext.resource.OutdatedStateManager.exec(OutdatedStateManager.java:70)
    at org.eclipse.xtext.ui.editor.model.XtextDocument$XtextDocumentLocker.internalReadOnly(XtextDocument.java:525)
    at org.eclipse.xtext.ui.editor.model.XtextDocument$XtextDocumentLocker.readOnly(XtextDocument.java:497)
    at org.eclipse.xtext.ui.editor.model.XtextDocument.readOnly(XtextDocument.java:136)
    at org.eclipse.xtext.util.concurrent.IReadAccess.tryReadOnly(IReadAccess.java:53)
    at org.eclipse.xtext.util.concurrent.IReadAccess.tryReadOnly(IReadAccess.java:71)
    at org.eclipse.xtext.ui.editor.hyperlinking.DefaultHyperlinkDetector.detectHyperlinks(DefaultHyperlinkDetector.java:46)
rlogiacco commented 4 years ago

I just noticed: what do you have at line 1 in the feature file?

Please post an example feature file which causes the problem.

mikeauen commented 4 years ago

@rlogiacco Line 1 is just tags. Here is an example:

@exclude
Feature: Login

  @trxloginAccp
  Scenario Outline: Login to TRX accp
    Given I login to "Acceptance" "TRX" with the "<role>" role
    Then I am navigated to the "Transactions - Transaction Overview" page

    Examples: 
      | role                    |
      | Transaction_Manager     |
      | Transaction_Coordinator |
miklossy commented 4 years ago

Based on the stacktrace from @mikeauen I could reproduce the problem with the following java program:

public class Main {

    public static void main(String[] args) {
        String pattern = "I navigate to {string} in the left hand menu";

        boolean result = "".matches(pattern);
        System.out.println(result);
    }

}

Executing this java program produces the same exception:

Exception in thread "main" java.util.regex.PatternSyntaxException: Illegal repetition near index 13
I navigate to {string} in the left hand menu
             ^
    at java.util.regex.Pattern.error(Unknown Source)
    at java.util.regex.Pattern.closure(Unknown Source)
    at java.util.regex.Pattern.sequence(Unknown Source)
    at java.util.regex.Pattern.expr(Unknown Source)
    at java.util.regex.Pattern.compile(Unknown Source)
    at java.util.regex.Pattern.<init>(Unknown Source)
    at java.util.regex.Pattern.compile(Unknown Source)
    at java.util.regex.Pattern.matches(Unknown Source)
    at java.lang.String.matches(Unknown Source)
    at naturaltest.Main.main(Main.java:10)

The problem can be fixed by quoting the regex parameter of the String.matches(String regex) method call so that it represents a properly formatted reqular expression even if the text contains regex symbols like { and }.

@drkstr101 Could you please take a look and provide a PR with the corresponding fix?

screencast

drkstr101 commented 4 years ago

This is using cucumber-jvm5 compatible syntax. In theory it should not be that difficult to add support in next. I had some WIP updates to the stepmatcher, but had backed them out to focus on the grammar lang for this release. In theory we just need to iterate the Literal+ nodes in RawText and pluck out those which have a grammerElement of STRING or NUMBER, provided a non regex string in the step annotation.

drkstr101 commented 4 years ago

This is a lot more involved than I originally thought. However, the upcoming release should treat these as a mismatched step, which would then be a configurable warning rather than a straight-up runtime exception thrown during validation.

drkstr101 commented 4 years ago

@miklossy Thanks for the tip! I've added some additional error protection as you pointed out in your example. I should have tested against this new syntax once the stepmatcher was updated to target the new Gherkin annotation namespace. I've added an example to the stepmatcher test, and it is now at least flagging it as a mismatched step rather than a runtime exception. Perhaps we could add at least add some simple token matchers for things like {string} and {number}. Like something that can be done in a few lines of code.

rlogiacco commented 4 years ago

For having it working as expected in relation to step matching we will have to:

  1. Define a new non-terminal element
  2. match curly braces and store the content
  3. find if a method with the appropriate annotation and name exists in the glue codebase

We can decide to skip the third step (I believe it's not going to be a very fast operation) and avoid the storing part of the second step, but that will imply either limited usability of the click-through feature or a true pain in the ass.

On Thu, Sep 10, 2020 at 2:29 AM Aaron R Miller notifications@github.com wrote:

@miklossy https://github.com/miklossy Thanks for the tip! I've added some additional error protection https://github.com/rlogiacco/Natural/blob/4b29b1c817e664eaefec0c4b13e243e98adb25ad/org.agileware.natural.stepmatcher.ui/src/org/agileware/natural/stepmatcher/ui/JavaAnnotationMatcher.java#L35 as you pointed out in your example. I should have tested against this new syntax once the stepmatcher was updated to target the new Gherkin annotation namespace. I've added an example to the stepmatcher test, and it is now at least flagging it as a mismatched step rather than a runtime exception. Perhaps we could add at least add some simple token matchers for things like {string} and {number}. Like something that can be done in a few lines of code.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub https://github.com/rlogiacco/Natural/issues/87#issuecomment-689896087, or unsubscribe https://github.com/notifications/unsubscribe-auth/AABQWMJ7BKWCSAGI3XMM4D3SFAMVVANCNFSM4QHQWULA .

drkstr101 commented 4 years ago

What About something like this?

public class CucumberExpressionValidator {

    private static final Pattern TOKEN_PATTERN = Pattern.compile("(?|({\\w+})|(\\(\\w+(\\s\\w+)?\\)))");

    public static boolean isMatchingAnnotationValue(final String annotationValue, final String description) {
        return matchRegex(annotationValue, description) || matchExpression(annotationValue, description);
    }

    private static boolean matchRegex(final String annotationValue, final String description) {
        try {
            return description.matches(Pattern.quote(annotationValue));
        } catch (final PatternSyntaxException e) {
            // PASS
        }

        return false;
    }

    private static boolean matchExpression(final String annotationValue, final String description) {
        int lastIndex = 0;
        final StringBuilder result = new StringBuilder();
        final Matcher matcher = TOKEN_PATTERN.matcher(annotationValue);
        while (matcher.find()) {
            result.append(annotationValue, lastIndex, matcher.start()).append(convertToken(matcher.group(1)));
            lastIndex = matcher.end();
        }

        if (lastIndex < annotationValue.length()) {
            result.append(annotationValue, lastIndex, annotationValue.length());
        }

        try {
            return description.matches(Pattern.quote(result.toString()));
        } catch (final PatternSyntaxException e) {
            e.printStackTrace();
        }

        return false;
    }

    private static String convertToken(final String token) {
        // TODO replace with equiv regex

        return token;
    }
}

This might be a little slow, however. I am not sure how best to branch between the two forms.

rlogiacco commented 4 years ago

I would keep this aside for now: let's focus on what we currently have. Once we get it working as expected we start adding features

drkstr101 commented 4 years ago

Agreed.

adityadubey057 commented 3 years ago

Hi Team, Is there a fix for the same ?? I am facing the same issue as soon as I edited my Feature File on the First Line "Error Executing EValidator"

And this is the error I am getting on my Error Logs

java.util.regex.PatternSyntaxException: Illegal repetition near index 24 Add APILoginPayLoad with {string} {string} {string} {string} {string} ^ at java.util.regex.Pattern.error(Unknown Source) at java.util.regex.Pattern.closure(Unknown Source) at java.util.regex.Pattern.sequence(Unknown Source) at java.util.regex.Pattern.expr(Unknown Source) at java.util.regex.Pattern.compile(Unknown Source) at java.util.regex.Pattern.(Unknown Source) at java.util.regex.Pattern.compile(Unknown Source) at java.util.regex.Pattern.matches(Unknown Source) at java.lang.String.matches(Unknown Source) at org.agileware.natural.common.JavaAnnotationMatcher.findMatches(JavaAnnotationMatcher.java:71) at org.agileware.natural.cucumber.validation.CucumberJavaValidator.checkStepMatching(CucumberJavaValidator.java:20) at sun.reflect.GeneratedMethodAccessor61.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) at java.lang.reflect.Method.invoke(Unknown Source) at org.eclipse.xtext.validation.AbstractDeclarativeValidator$MethodWrapper.invoke(AbstractDeclarativeValidator.java:129) at org.eclipse.xtext.validation.AbstractDeclarativeValidator.internalValidate(AbstractDeclarativeValidator.java:337) at org.eclipse.xtext.validation.AbstractInjectableValidator.validate(AbstractInjectableValidator.java:72) at org.eclipse.xtext.validation.CompositeEValidator.validate(CompositeEValidator.java:151) at org.eclipse.emf.ecore.util.Diagnostician.doValidate(Diagnostician.java:299) at org.eclipse.emf.ecore.util.Diagnostician.validate(Diagnostician.java:245) at org.eclipse.xtext.validation.CancelableDiagnostician.validate(CancelableDiagnostician.java:41) at org.eclipse.emf.ecore.util.Diagnostician.validate(Diagnostician.java:200) at org.eclipse.emf.ecore.util.Diagnostician.validate(Diagnostician.java:142) at org.eclipse.xtext.validation.ResourceValidatorImpl.validate(ResourceValidatorImpl.java:147) at org.eclipse.xtext.validation.ResourceValidatorImpl.validate(ResourceValidatorImpl.java:125) at org.eclipse.xtext.validation.ResourceValidatorImpl.validate(ResourceValidatorImpl.java:91) at org.eclipse.xtext.ui.editor.validation.ValidationJob$1.exec(ValidationJob.java:92) at org.eclipse.xtext.ui.editor.validation.ValidationJob$1.exec(ValidationJob.java:1) at org.eclipse.xtext.util.concurrent.CancelableUnitOfWork.exec(CancelableUnitOfWork.java:27) at org.eclipse.xtext.util.concurrent.WrappingCancelableUnitOfWork.exec(WrappingCancelableUnitOfWork.java:58) at org.eclipse.xtext.util.concurrent.CancelableUnitOfWork.exec(CancelableUnitOfWork.java:27) at org.eclipse.xtext.resource.OutdatedStateManager.exec(OutdatedStateManager.java:70) at org.eclipse.xtext.ui.editor.model.XtextDocument$XtextDocumentLocker.internalReadOnly(XtextDocument.java:525) at org.eclipse.xtext.ui.editor.model.XtextDocument$XtextDocumentLocker.readOnly(XtextDocument.java:497) at org.eclipse.xtext.ui.editor.model.XtextDocument.readOnly(XtextDocument.java:136) at org.eclipse.xtext.util.concurrent.IReadAccess.tryReadOnly(IReadAccess.java:50) at org.eclipse.xtext.ui.editor.validation.ValidationJob.createIssues(ValidationJob.java:87) at org.eclipse.xtext.ui.editor.validation.ValidationJob.run(ValidationJob.java:68) at org.eclipse.core.internal.jobs.Worker.run(Worker.java:60)

image