Karate: one liner json path expression not working - karate

I have a two line json path expression that prints something and I want to put it all in one line:
Given path 'device/'
When method get
Then status 200
#This correctly prints the value:
And def device_search = $.device[?(#.manufacturer == 'a manufacturer')]
And print device_search[0].id
#This doesn't work (prints null):
And print $.device[?(#.manufacturer == 'a manufacturer')][0].id
Thanks!

This is not supported. Use 2 steps.
But if you insist, use karate.get().
And print karate.get("$.device[?(#.manufacturer == 'a manufacturer')][0].id")

Related

Why won't Karate let me read in variables from another feature file?

If I have feature file A I should be able to call feature file B to use as a store of file contants.
So, like:
def MyExpectedResult = read call(MyExpectedResultContants.feature)
Given <endpoint>
When get
Then status 200
And match response contains MyExpectedResult
This is not supported after spending a lot of time trying to get that to work. A constants file is a basic thing it would be nice if Karate supported.
Let's say in constants.feature you have :
def variable1 = "string1"
def variable2 = { json: "value" }
If you call
def constants = call read(constants.feature)
Then you can do
* match constants.variable1 == "string1"
* match constants.variable2.json == "value"
If that's not what you want, then you should edit your post.

How to fix UnboundLocalError: local variable 'file_lines' referenced before assignment

So this is my function which is meant to read the lines of text from a file.
This is extracted from a larger program hence some of the comments may seem out of place. Anyways I need to use the functions text and file_lines in numerous other functions but even after declaring them as global I still get the UnboundLocalError: local variable 'file_lines' referenced before assignment error and I don't know what to do.
import sys
text = []
case = ''
file_lines = []
def read_file(file): # function to read a file and split it into lines
global text #sets variable text as a global variable for use in multiple locations
global case #handles case sensitivity.
try: #tests the statement after colon
open(file)
except:
print('oops no file found bearing that name')
else:
while file == '': #if the file name is blank print error, this prevents program from crashing
print ('error')
filename = input('enter a file and its extension ie file.ext\n>>')
with open(file) as f : #opens filewith name
text = f.read() #read all lines of program text.
print ("file successfully read")
print('TEXT SENSITIVITY TURNED ON !!!!!!')
text = text.split('\n')# breaks lines in file into list instead of using ".readlines"
# so that the program doesn't count blank lines
case == True
global file_lines
file_lines = text
a function that tries to use the read_lines variable would be
def find_words(words):
line_num = 0 # to count the line number
number_of_word = 0
if case == False:
words = words.lower()
file_lines = [file_lines.lower() for file_lines in text]
while "" in file_lines:
file_lines.remove('')
for lines in file_lines:
line_num += 1
if words in lines: #checks each for the words being looks for
print(line_num,"...", text[line_num-1])
number_of_word = 1
if number_of_word == 0: #to check if the word is located in the file
print('Words not found')
In your function find_words you forgot to specify that find_lines is global. Try
def find_words(words):
global file_lines
line_num = 0 # to count the line number
The function errors because file_lines is not defined within the scope of find_words otherwise.

saving and deleting fileI/O

Two part question.
First, how can i change this(i've tried using 'for' but i cant figure it out) so that it saves like;
'key value' instead of '{key: value}'.
with open("phonebook.txt", "w") as x:
json.dump(a, x)
Second, how do you delete from a file by using the users input.
I cannot see a way of changing this to delete from file instead of the dict 'a';
name = input("enter name of contact you want to delete: ")
if name in a:
del a[name]
EDIT. This is what ive done now but it doesnt do whats expected ( i also tried adding the .readlines where x is but it just gets errors.
def save(a):
with open("phonebook.txt", "w") as x:
for k in a:
json.dump(str(k)+" "+str(a[k]), x)
def load():
a = {}
with open("phonebook.txt", "r") as f:
for l in f:
a[l[0]] = l[1]
print (a)
def save works fine (as far as i can see anyway)
Also i have tried c = l.split() and a[c[0]] = c[1]. Just doesnt want to work !
First part
That's not JSON format. Do not use it if you need something else. Use plain text files, like
with open("phonebook.txt","w") as file :
for key, value in a.items() :
file.write(str(key)+" "+str(value))
Second part
It looks you loaded the file into dictionary a. In that case, you just need to write dictionary a back to the file after deleting. If you have not loaded the file into the dictionary yet, you can do it with:
a= {}
with open("phonebook.txt") as file :
for line in file.readlines() :
content= line.split()
a[content[0]]= content[1]

grails internationalization (i18n)

i work on grails project
def result = "customer"
//(this value is according to returned method parameter,
//it may be customer, company,... & so on)
def messages = "${message(code: 'default.result.${result}', default:'${result}')}"
i need to send a variable inside message code as i mention above
problem: this code appears as
default.result.${result}
that there is no code in message.properties refer to these code
there is default.result.customer ....$ so on
Question: how can i send variable inside message Code?
Try omitting the double quotes (GString) and it should work like the following:
def xxx = "bar"
def m = message(code: "foo.${xxx}", args: ['hello world'])
Results in following message-code
foo.bar
Try:
def messages = message(code: 'default.result.' + result, default: result)
If you want to pass in some values, e.g. a string, you can define your message like this:
default.result.success = Action {0} was successfull.
And resolve your code like this:
def m = message(code: 'default.result.' + result, args: ['delete User'])

"Pythonic" equivalent for handling switch and multiple string compares

Alright, so my title sucked. An example works better:
input = 'check yahoo.com'
I want to parse input, using the first word as the "command", and the rest of the string as a parameter. Here's the simple version of how my non-Pythonic mind is coding it:
if len(input) > 0:
a = input.split(' ')
if a[0] == 'check':
if len(a) > 1:
do_check(a[1])
elif a[0] == 'search':
if len(a) > 1:
do_search(a[1])
I like Python because it makes normally complicated things into rather simple things. I'm not too experienced with it, and I am fairly sure there's a much better way to do these things... some way more pythonic. I've seen some examples of people replacing switch statements with dicts and lambda functions, while other people simply recommended if..else nests.
dispatch = {
'check': do_check,
'search': do_search,
}
cmd, _, arg = input.partition(' ')
if cmd in dispatch:
dispatch[cmd](arg)
else:
do_default(cmd, arg)
I am fairly sure there's a much better way to do these things... some way more pythonic.
Not really. You code is simple, clear, obvious and English-like.
I've seen some examples of people replacing switch statements with dicts and lambda functions,
Yes, you've seen them and they're not clear, obvious or English-like. They exist because some people like to wring their hands over the switch statement.
while other people simply recommended if..else nests.
Correct. They work. They're simple, clear, ...
Your code is good. Leave it alone. Move on.
This lets you avoid giving each command name twice; function names are used almost directly as command names.
class CommandFunctions:
def c_check(self, arg):
print "checking", arg
def c_search(self, arg):
print "searching for", arg
def c_compare(self, arg1, arg2):
print "comparing", arg1, "with", arg2
def execute(self, line):
words = line.split(' ')
fn = getattr(self, 'c_' + words[0], None)
if fn is None:
import sys
sys.stderr.write('error: no such command "%s"\n' % words[0])
return
fn(*words[1:])
cf = CommandFunctions()
import sys
for line in sys.stdin:
cf.execute(line.strip())
If you're looking for a one liner 'pythonic' approach to this you can use this:
def do_check(x): print 'checking for:', x
def do_search(x): print 'searching for:', x
input = 'check yahoo.com'
{'check': do_check}.get(input.split()[0], do_search)(input.split()[1])
# checking for: yahoo.com
input = 'search google.com'
{'check': do_check}.get(input.split()[0], do_search)(input.split()[1])
# searching for: google.com
input = 'foo bar.com'
{'check': do_check}.get(input.split()[0], do_search)(input.split()[1])
# searching for: bar.com
Disregard, I just realized that my answer was similar to one of the other answers - and apparently there's no delete key :)
Variation on #MizardX's answer:
from collections import defaultdict
dispatch = defaultdict(do_default, check=do_check, search=do_search)
cmd, _, arg = input.partition(' ')
dispatch[cmd](arg)