I can test the content after a redirection like this
assert "/url" = redir_path = redirected_to(conn, 302)
conn = get(recycle(conn), redir_path)
assert html_response(conn, 200) == "Content after redirection"
But I cannot add a param variable to the assert url like this:
id = 10
assert "/url/#{id}" = redir_path = redirected_to(conn, 302)
It complains with:
cannot invoke remote function id/0 inside match
So if I just define the path like this before using it:
url_path = "/url/%{id}"
assert url_path = redir_path = redirected_to(conn, 302)
warning: variable "url_path" is unused
?? unusued? is it being used inside the assert...
Not sure how to silence that warning or how to approach this.
The code is similar to Chris's response here:
https://elixirforum.com/t/following-redirection-in-controllertests/10084
warning: variable "url_path" is unused
?? unusued? is it being used inside the assert...
No, it's not. Your assert will match any value because if you have a variable name on the LHS of a match, it matches any value and that variable gets assigned the value of the RHS.
In:
foo = 10
assert foo = 20
IO.inspect foo
the assert passes and foo is printed as 20.
If you just want to assert that that string equals the value returned by redirected_to/2, you can use ==:
assert "/url/#{id}" == redirected_to(conn, 302)
Related
Let's define 2 classes
A.gd
class_name A
var v = null
func _init(v_):
v = v_
B.gd
class_name B
var v = null
Now, when I try to use str2var/var2str, this is what I get
var a = A.new("aaa")
var b = B.new()
b.v = "bbb"
printt("var2str(a):", var2str(a))
printt("var2str(b):", var2str(b))
printt ("var2str(str2var(var2str(a))):", var2str(str2var(var2str(a))))
printt ("var2str(str2var(var2str(b))):", var2str(str2var(var2str(b))))
Output:
var2str(a): Object(Reference,"script":Resource( "res://Scripts/AI/A.gd"),"v":"aaa")
var2str(b): Object(Reference,"script":Resource( "res://Scripts/AI/B.gd"),"v":"bbb")
var2str(str2var(var2str(a))): Object(Reference,"script":null)
var2str(str2var(var2str(b))): Object(Reference,"script":Resource( "res://Scripts/AI/B.gd"),"v":"bbb")
Why is str2var(a) not working?
How should I fix it?
The Solution
Fix it by making the parameter optional, for example:
class_name A
var v = null
func _init(v_ = null):
v = v_
With that there is no error. I get this output:
var2str(a): Object(Reference,"script":Resource( "res://A.gd"),"v":"aaa")
var2str(b): Object(Reference,"script":Resource( "res://B.gd"),"v":"bbb")
var2str(str2var(var2str(a))): Object(Reference,"script":Resource( "res://A.gd"),"v":"aaa")
var2str(str2var(var2str(b))): Object(Reference,"script":Resource( "res://B.gd"),"v":"bbb")
The problem
For abstract, str2var will not pass any arguments to _init. It would not know what to pass anyway.
The rest of the answer is the process of confirming that str2var will result in calling _init with no argument.
When I try your code I get this error:
E 0:00:00.630 _create_instance: Condition "r_error.error != Variant::CallError::CALL_OK" is true. Returned: __null
<C++ Source> modules/gdscript/gdscript.cpp:121 # _create_instance()
<Stack Trace> main.gd:12 # _ready()
We can find the line that throws the error in _create_instance by looking at the source.
Sadly that does not give me much information. So, I decided to search how str2var is implemented.
We find it inside GDScriptFunctions::call, here. Which calls VariantParser::parse, which calls VariantParser::parse_value. We are interested in the case of an "Object" (here). And that results in a call to ClassDB::instance(type). There type will be "Reference", and then it procedes to set all properties as they come. Being the first one "script":Resource("res://A.gd").
When we set the script (here), it will result in a call to GDScript::instance_create. Which calls GDScript::_create_instance (here):
return _create_instance(NULL, 0, p_this, Object::cast_to<Reference>(p_this) != NULL, unchecked_error)
With no argument for _init (The NULL is the argument array, and 0 is the number of arguments). This is the signature for GDScript::_create_instance:
GDScriptInstance *GDScript::_create_instance(const Variant **p_args, int p_argcount, Object *p_owner, bool p_isref, Variant::CallError &r_error)
Of course, initializer->call(instance, p_args, p_argcount, r_error); fails, because _init requires an argument. And we find the line that throws the error further down. Note: initializer is created while parsing the script.
When we are providing the input whose datatype is boolean passed in POST API and validating it with GET API which return value in string
eg:
* def a = 'false' // result from GET API
* def b = false //input
* match a == b
Expected Result : It should fail as the datatype is different
Actual Result ": scenario is showing PASS
Why is it passing?
whereas, I also noticed when I an validating the data from database whose column datatype is string and we are matching the data with boolean value
i.e
* match 'false' == false
Expected Result : It should fail
Actual Result : scenario is failed
I believe the issue is related to this https://github.com/intuit/karate/issues/1179
seems like it has been fixed recently. you can build the code following this https://github.com/intuit/karate/wiki/Developer-Guide#build, else it will be next release.
You can use this option to check for if else inside a feature
Scenario: if else
* def val = 'test'
# * def result = <condition> ? <true value> : <false value>
* def result = val == 'test' ? 'TRUE' : 'FALSE'
* print result
so my code is as follows:
* def value = newMP.response.data[randomizer].phoneNumber
* def nullvalue = 'null'
* def filter = (value == '#null' ? nullvalue : value)
* print filter
And param filter[phoneNumber] = filter
The result of this code is
Thing is that my application allows a search for null as well. therefore im looking if its possible to put in a filter that is null based on the conditional logic
Additionally if i go like this
And param filter[phoneNumber] = 'null'
the null value is in the GET call
Yes by default Karate ignores null-valued params and this is what most users expect.
You have not been clear as to what you are expecting but I'm guessing you need a param with an empty value.
Try this:
And param filter = ''
Also read this example for more ideas: https://github.com/intuit/karate/blob/master/karate-demo/src/test/java/demo/search/dynamic-params.feature
What i required was to put in the value of the parameter as either null or "null", and the validate in response that the value is null, not the string form of it. below is the workaround for it.
And def value = newMP.response.data[randomizer].phoneNumber
And eval if (value == null) karate.set('value', 'null')
And param filter[phoneNumber] = value
When method GET
Then status 200
* eval if (value == 'null') karate.set('value', null)
Then match response.data[0].attributes.phoneNumber contains value
I have a variable that contains the name of another variable which I want to retrieve the value, e.g.:
def variable = "finalVariableValue"
def variableName = "variable"
How can I get variable.value as I only know variableName?
I've seen the a Binding could be used but I have a lot of variable that I need to put on this Binding object in order to make it works. Is the only way?
NB: this behaviour is really similar to the ant property extension mechanism.
Thanks,
Michele.
By prefixing it with def you are not registering it in an object you can inspect, like a map; one could argue it is registered in the AST, but that is a rocky road.
My 0.03 are working with a map, with a binding, or with dynamic properties. Drop the def part and choose one of the solutions:
Map
Simply declare the variable as a key in a map:
def map = [:]
map.variable = "finalVariableValue"
def variableName = "variable"
assert map[variableName] == "finalVariableValue"
Binding (with script)
Use the script built-in binding. Note this only works with scripts:
variable = "finalVariableValue"
variableName = "variable"
assert binding[variableName] == "finalVariableValue"
Dynamic properties
Use some dynamic properties mechanism, like an Expando (also, you could use getProperty with setProperty and others):
class Container extends Expando {
def declare() {
variable = "finalVariableValue"
variableName = "variable"
}
}
c = new Container()
c.declare()
assert c[c.variableName] == "finalVariableValue"
You can use the script's scope, simply dropping the Type definition:
variable = 'value'
name = 'variable'
assert 'variable' == this.name
assert 'value' == this[this.name]
or using #Field annotation:
import groovy.transform.Field
#Field def variable = 'value'
#Field def name = 'variable'
assert 'variable' == this.name
assert 'value' == this[this.name]
While reading some groovy code of another developer I encountered the following definition:
def foo=[:]
What does it mean?
[:] is shorthand notation for creating a Map.
You can also add keys and values to it:
def foo = [bar: 'baz']
[:] creates an empty Map. The colon is there to distinguish it from [], which creates an empty List.
This groovy code:
def foo = [:]
is roughly equivalent to this java code:
Object foo = new java.util.LinkedHashMap();
Quoting the doc:
Notice that [:] is the empty map expression.
... which is the only Map with size() returning 0. ) By itself, it's rarely useful, but you can add values into this Map, of course:
def emptyMap = [:]
assert emptyMap.size() == 0
emptyMap.foo = 5
assert emptyMap.size() == 1
assert emptyMap.foo == 5