-
-
Notifications
You must be signed in to change notification settings - Fork 2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Adding unit tests to test and reproduce several scenarios with readin… #1436
Adding unit tests to test and reproduce several scenarios with readin… #1436
Conversation
…g files and reusing variables across features
@ptrthomas minimal scenario to replicate #1373 (comment) is the js-read-4.feature : js-read-4.feature
js-read-called-2.feature
Issue happens when the called feature calls and the called feature calls another feature in background adding it's variables. |
After checking this in I realized I could try this: js-read-called-2.feature
And it works. The difference is that on the the called feature we are assigning the result of another called feature to a variable. So it's probably the piece of code that "adds" the content/variables of the called feature in the background that is somehow overriding/removing the __arg . I haven't tried other keywords yet like __row , __num for Outlines btw the print statement returns this: It's just the print statement. Added a match to the PR and the content of __arg can be easily used. |
@joelpramos I'm lost. any way to simplify - just focus on 1 case at a time instead of so many tests. also I see a build failure. will look at this later |
@joelpramos no worries. I just may have realized what the problem could me. just making one commit before logging off - hope that solves ! |
I got it - was refactoring now so that the magicVariables stay only within the scope of the ScenarioRuntime (ie don't add to the vars Map) but are added to the JS Engine. Let me know if that's what you're working towards. ++ and keeping any other variables outside of that magicVariables map so they are propagated with shared scope |
…ithin the Scenario or Scenario Outline being executed
…the scope of the Scenario they are no longer returned in the Scenario result, when being called.
@ptrthomas made the changes for the magicVariables being available only within the Scenario or Scenario Outline being executed - ie if a scenario is called that scenario won't have changes to __arg (for e.g.) even if in shared score. When reviewing let me know if this would be an intended design that aligns with your thoughts. Also check out Especially the later. That was an unintended consequence in which those variables are now not getting returned when assigning the result of a called feature (diff in the PR should be obvious). I can give it some thought into how to work around it / make it work as before if you think it's important (maybe adding in the scenario result when the execution of the scenario is over could be an option but my concern is it's complex as we will "pollute" the variables of the caller). |
@@ -95,7 +95,7 @@ public ScenarioRuntime(FeatureRuntime featureRuntime, Scenario scenario, Scenari | |||
// detaching is as good as cloning | |||
// the detach is needed as the js-engine will be different | |||
Map<String, Variable> detached = background.engine.detachVariables(); | |||
detached.forEach((k, v) -> magicVariables.put(k, v.getValue())); | |||
detached.forEach((k, v) -> this.engine.vars.put(k, v)); // maybe this should go into this.engine.vars |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
forgot to remove the comment from the check in
@@ -248,6 +248,8 @@ protected void logError(String message) { | |||
} | |||
|
|||
private Map<String, Object> initMagicVariables() { | |||
// do not init anything in this map that couldn't be considered a magic var (e.g. __arg, __loop) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
need to add the other two vars in the comment for documentation purposes
@joelpramos ok so I made one change which puts the background in the engine variables. which hopefully solves some of the problems you outlined - but I'm finding it hard to understand some of it. btw I don't handle large diffs well. and this is one of the most complex areas of karate. some thoughts below
so I propose a) see if my fix solves 80% of the problems |
will not be visible to calling features, which IMO is good, less variable clutter decision is to keep __arg __loop __row and __num as [hidden] variables they will continue to be [visible] to called features but thats about it and of course be available to use in any js expression / assertion this shold hoefully solve all problems discussed in #1436 callonce also looks good, we have one existing test [callonce-bg.feature]
@joelpramos ok I think I have a solution for all the problems, explained / details in this commit: 426e9c0 so maybe all we need is some extra tests that you see fit ! |
@ptrthomas Yeah those changes would work (although I haven't run the unit tests yet). I'd suggest one more thing - see the changes I did at ScenarioRuntime:initMagicVariables(). In that method we are adding to the map the variables from the caller feature and the variables from the Examples table. With the Map stored on that variable we will iterate add set those variables as hidden variables (your code change in the Scenario Engine). I haven't tried your PR yet with the tests but as a principle I'd suggest we initialize only those special variables in that method and do a setVariables() for both caller and examples table variables to the ScenarioRuntime vars property in the Engine. See here: ScenarioEngine.java:init() in my PR. Proposed additional snippet in the init() method below:
My gut feeling is that your PR works completely because there's a line here that sets all the magicVariables from the caller and so it doesn't really make a difference but as a design principle I'd keep that function initMagicVariables() only with the responsibility of keeping those indeed magical variables. The responsibility of setting variables as part of the shared context or not is already delegated by the caller in which the vars map is either passed as reference or a deep copy (which come to think of it passing those variables in the initMagicVariables() might actually give "write" access to called features in when context is not shared). |
As per unit tests - I'm pleased with the ones on this PR, once we finish the work in the develop branch I'll close this one and open a new one with just the tests. I'll do a review to confirm whether I've covered all the scenarios with callonce as well (probably not as you can see there were a lot of different cases I could think of :) ) |
the "hidden" variable approach solves this problem nicely they will not be "mutated" by called features to any depth. which also may be the reason why your other concerns may not be valid. do have a closer look and see what you think, I felt it is reasonably elegant. I think we will have cases where users make a call (just after landing from another call) and expect variables to be in scope (even though I hate this) hence the need for copying parent variables over. lets see if you can find any edge cases via your tests |
… Note that PR will not be merged.
Closed as per discussion. See unit tests at this PR #1438 |
Description
Thanks for contributing this Pull Request. Make sure that you submit this Pull Request against the
develop
branch of this repository, add a brief description, and tag the relevant issue(s) and PR(s) below.