Skip to content

Commit

Permalink
[breaking] some magic variables e.g. __loop and __arg
Browse files Browse the repository at this point in the history
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]
  • Loading branch information
ptrthomas committed Jan 17, 2021
1 parent 7095b6f commit 426e9c0
Show file tree
Hide file tree
Showing 9 changed files with 40 additions and 14 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -994,7 +994,7 @@ public void doc(String exp) {
public void init() { // not in constructor because it has to be on Runnable.run() thread
JS = JsEngine.local();
logger.trace("js context: {}", JS);
setVariables(runtime.magicVariables);
runtime.magicVariables.forEach((k, v) -> setHiddenVariable(k, v));
attachVariables(); // re-hydrate any functions from caller or background
setHiddenVariable(KARATE, bridge);
setHiddenVariable(READ, readFunction);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,10 @@ private Map<String, Object> initMagicVariables() {
map.putAll(caller.arg.getValue());
}
} else {
// karate principle: parent variables are always "visible"
// so we inject the parent magic variables
// but they will be over-written by what is local to this scenario
map.putAll(caller.parentRuntime.magicVariables);
map.put("__arg", caller.arg);
map.put("__loop", caller.getLoopIndex());
if (caller.arg != null && caller.arg.isMap()) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,11 @@ void testToBean() {
@Test
void testOutlineBackground() {
run("outline-background.feature");
}
}

@Test
void testCallArg() {
run("call-arg.feature");
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@ void testPerfHook1() {
assertEquals(featureResult.getScenarioCount(), 1);
assertEquals(featureResult.getPassedCount(), 1);
assertEquals(featureResult.getFailedCount(), 0);
matchContains(featureResult.getVariables(), "{ bar: '" + bar + "', configSource: 'normal', responseStatus: 200, response: { foo: ['" + bar + "'] } }");
matchContains(featureResult.getVariables(), "{ configSource: 'normal', responseStatus: 200, response: { foo: ['" + bar + "'] } }");
}

@Test
Expand All @@ -77,7 +77,7 @@ void testPerfHook2() {
assertEquals(featureResult.getScenarioCount(), 1);
assertEquals(featureResult.getPassedCount(), 0);
assertEquals(featureResult.getFailedCount(), 1);
matchContains(featureResult.getVariables(), "{ bar: '" + bar + "', configSource: 'normal', responseStatus: 200, response: { foo: ['" + bar + "'] } }");
matchContains(featureResult.getVariables(), "{ configSource: 'normal', responseStatus: 200, response: { foo: ['" + bar + "'] } }");
}

@Test
Expand All @@ -94,7 +94,7 @@ void testPerfHook3() {
assertEquals(featureResult.getScenarioCount(), 1);
assertEquals(featureResult.getPassedCount(), 0);
assertEquals(featureResult.getFailedCount(), 1);
matchContains(featureResult.getVariables(), "{ bar: '" + bar + "', configSource: 'normal', responseStatus: 200, response: { foo: ['" + bar + "'] } }");
matchContains(featureResult.getVariables(), "{ configSource: 'normal', responseStatus: 200, response: { foo: ['" + bar + "'] } }");
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -140,23 +140,23 @@ void testCallKarateFeature() {
"def b = 'bar'",
"def res = call read('called1.feature')"
);
matchVar("res", "{ a: 1, b: 'bar', foo: { hello: 'world' }, configSource: 'normal', __arg: null, __loop: -1 }");
matchVar("res", "{ a: 1, b: 'bar', foo: { hello: 'world' }, configSource: 'normal' }");
run(
"def b = 'bar'",
"def res = call read('called1.feature') { foo: 'bar' }"
);
matchVar("res", "{ a: 1, b: 'bar', foo: { hello: 'world' }, configSource: 'normal', __arg: { foo: 'bar' }, __loop: -1 }");
matchVar("res", "{ a: 1, b: 'bar', foo: { hello: 'world' }, configSource: 'normal' }");
run(
"def b = 'bar'",
"def res = call read('called1.feature') [{ foo: 'bar' }]"
);
matchVar("res", "[{ a: 1, b: 'bar', foo: { hello: 'world' }, configSource: 'normal', __arg: { foo: 'bar' }, __loop: 0 }]");
matchVar("res", "[{ a: 1, b: 'bar', foo: { hello: 'world' }, configSource: 'normal' }]");
run(
"def b = 'bar'",
"def fun = function(i){ if (i == 1) return null; return { index: i } }",
"def res = call read('called1.feature') fun"
);
matchVar("res", "[{ a: 1, b: 'bar', foo: { hello: 'world' }, configSource: 'normal', __arg: { index: 0 }, __loop: 0, index: 0, fun: '#ignore' }]");
matchVar("res", "[{ a: 1, b: 'bar', foo: { hello: 'world' }, configSource: 'normal', fun: '#ignore' }]");
}

@Test
Expand Down Expand Up @@ -215,7 +215,7 @@ void testCallFromJs() {
run(
"def res = karate.call('called1.feature')"
);
matchVar("res", "{ a: 1, foo: { hello: 'world' }, configSource: 'normal', __arg: null, __loop: -1 }");
matchVar("res", "{ a: 1, foo: { hello: 'world' }, configSource: 'normal' }");
}

@Test
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
Feature:

Background:
* match __arg == { foo: 'bar' }
* call read('call-arg-common.feature')

Scenario:
* print 'in scenario'
* match __arg == { foo: 'bar' }
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
Feature:

Scenario:
* def hello = function(){ return 'hello' }
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
Feature:

Background:
* print 'in background'

Scenario:
* def params = { 'foo': 'bar' }
* call read('call-arg-called.feature') params
4 changes: 0 additions & 4 deletions karate-demo/src/test/java/demo/calltable/call-table.feature
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,6 @@ Background:
# use json-path to 'un-pack' the array of kittens created
* def created = $result[*].response

# for each iteration, a variable called '__loop' is set for convenience
# which can be accessed in the called feature as well
* match result[*].__loop == [0, 1, 2, 3, 4, 5]

# which is not even needed for most data-driven assertions
* match created[*].name == $kittens[*].name

Expand Down

0 comments on commit 426e9c0

Please sign in to comment.