I'm trying to fetch the value from an attribute in the payload but Karate throws an error or simply doesn't fetch the value.
I've created a simplified version of my code to make it easier to understand.
* def lists = [{#id: 1, type: 'video'}, {#id: 2, type: 'image'}]
* def ser = {#id: 2, type: '#string'}
* def foundAt = []
* def fun = function(x, i){ if (karate.match(x, ser).pass) foundAt.add(i) }
* eval karate.forEach(lists, fun)
* def storeId = lists[foundAt[0]].#id
* def storeType = lists[foundAt[0]].type
* print storeId
* print storeType
print storeType will print the value as expected but print storeId will print the following error message:
javascript evaluation failed: lists[foundAt[0]].#id, <eval>:1:18 Expected ident but found error
lists[foundAt[0]].#id
^ in <eval> at line number 1 at column nu*mber 18
I expect the value '2' to be printed but clearly I'm doing something wrong?
One small change will do the trick since # is a "bad" character for JSON key-names:
* def storeId = lists[foundAt[0]]['#id']
Here's also a suggested simplification to your code:
* def fun = function(x, i){ return karate.match(x, ser).pass }
* def found = karate.filter(lists, fun)
* def storeId = found[0]['#id']
* def storeType = found[0].type
* print storeId
* print storeType
Related
I m trying to perform a little calculation and Logic on date.time with Flask application.
1.) the application will calculate the difference between issue date and expiry date called "remaining days" , The application will check if remaining days is less than 365 days and trigger a function
I attempted the first logic to manipulate the data and submit to database
`#bp.route('/cerpacs/add', methods=['GET', 'POST'])
#login_required
def add_cerpac():
"""
Add a an Cerpac/ expartriates to the database
"""
check_admin()
add_cerpac = True
form =CerpacForm()
if form.validate_on_submit():
cerpac = Cerpac(cerpac_serial_no=form.cerpac_serial_no.data,
cerpac_issue_date= form.cerpac_issue_date.data,
cerpac_exp_date=form.cerpac_exp_date.data,
employee =form.employee.data, )
form.cerpac_issue_date.data = cerpac.cerpac_issue_date
form.cerpac_exp_date.data = cerpac.cerpac_exp_date
if request.method == 'POST':
todays_date = datetime.now()
t = cerpac.cerpac_issue_date
t1 = cerpac.cerpac_exp_date
remaining_days = t1 - t
print(remaining_days) - good prints my result!
remaining_days = cerpac.remaining_days ----not adding to database
try:
add cerpac to the database
db.session.add(cerpac)
db.session.commit()
flash('You have successfully added a Cerpac.' )`
`
my model:
class Cerpac(db.Model):
__tablename__ = 'cerpacs'
id = db.Column(db.Integer, primary_key=True)
cerpac_issue_date = db.Column(db.DateTime)
cerpac_exp_date=db.Column(db.DateTime)
remaining_days = db.Column(db.DateTime)
cerpac_serial_no = db.Column(db.String(60))
cerpac_upload = db.Column(db.String(20), default='cerpac.jpg')
renew_status = db.Column(db.Boolean, default=False)
process_status = db.Column(db.Boolean, default=False)
renewcerpac_id = db.Column(db.Integer, db.ForeignKey('renewcerpacs.id'))
employee_id = db.Column(db.Integer, db.ForeignKey('employees.id'))
def __repr__(self):
return '<Cerpac {}>'.format(self.name) model:
I want to add this to database and eventually write a function like this:
I had a mistake also in the code because I had error issue_date not defined. How do I define issue_date as a date.time variable?
def remaining_days(issue_date, expired_date):
issue_date = datetime(issue_date)
days_to_go = expired - issue
if days_to_go == 365:
renew_status== True
print("time to renew")
print("We are Ok")
I would simplify this to something like:
from datetime import datetime
class Cerpac(db.Model):
...
cerpac_exp_date=db.Column(db.DateTime)
...
#property
def remaining_days(self):
return (self.cerpac_exp_date - self.cerpac_issue_date).days
#property
def days_to_expiry(self):
return (self.cerpac_exp_date - datetime.now()).days
Then, days_to_expiry and remaining_days become properties calculated when you query, and update automatically when they renew their cards.
For debugging purposes before writing out tests, I am looking to get the number of key:value pairs within the one object in the array.
Right now, I have this:
"items": [
{
"id": "6b0051ad-721d-blah-blah-4dab9cf39ff4",
"external_id": "blahvekmce",
"filename": "foo-text_field-XYGLVU",
"created_date": "2019-02-11T04:10:31Z",
"last_update_date": "2019-02-11T04:10:31Z",
"file_upload_date": "2019-02-11T04:10:31Z",
"deleted_date": null,
"released_and_not_expired": true,
"asset_properties": null,
"file_properties": null,
"thumbnails": null,
"embeds": null
}
]
When I write out:
* print response.items.length // returns 1
When I write out:
* print response.items[0].length it doesn't return anything
Any thoughts on how I can approach this?
There are multiple ways, but this should work, plus you see how to get the keys as well:
* def keys = []
* eval karate.forEach(response.items[0], function(x){ keys.add(x) })
* def count = keys.length
* match count == 12
Refer the docs: https://github.com/intuit/karate#json-transforms
Karate now provides karate.sizeOf() API to get count of an object.
* def object = { a: 1, b: 'hello' }
* def count = karate.sizeOf(object)
* match count == 2
Ref: https://github.com/karatelabs/karate#the-karate-object
count = 0
for (var v in response.items[0]) {
count = count + 1;
}
print(count)
I'm sending HTTP request from application 1
http://localhost:8888/inputs/example-input?ProductId=49823&Orders_orderId=27759
to application 2.
And in application 2 I'm reciving plain string:
inputs/example-input?ProductId=49823&Orders_orderId=27759
I need to get values in they own variables as shown:
def productId = 49823
def orderId = 27759
Is there some groovy way to parse input string inputs/example-input?ProductId=49823&Orders_orderId=27759?
You need to parse the input manually, e.g.:
def input = "inputs/example-input?ProductId=49823&Orders_orderId=27759"
def parsed = input
.split("\\?")[1]
.split("&")
.inject([:]) { m, e ->
def arr = e.split("=")
m[arr[0]] = arr[1]
m
}
def productId = parsed.ProductId
def orderId = parsed.Orders_orderId
assert productId == '49823'
assert orderId == '27759'
Serialization can fails with a class object created containing __pairs:
test = torch.class('test')
function test:__init()
self.data = {}
end
function test:__pairs(...)
return pairs(self.data, ...)
end
function test:get_data()
print(self.data)
end
a = test.new()
a.data = {"asdasd"}
b = torch.serialize(a)
c = torch.deserialize(b)
print(torch.typename(c))
print(c:get_data())
The following returns:
test
nil
The engine behind the torch.serialization is located in the File-class. The File:writeObject us the key function. For the above example the action for a Torch class starts at line 201 with the:
elseif typeidx == TYPE_TORCH then
The type is identified in the File:isWritableObject.
One could probably implement the metatable function write but in the above example the problem was non-torch metatable function __pairs that should be __pairs__ (see torch.getmetatable):
test = torch.class('test')
function test:__init()
self.data = {}
end
function test:__pairs__(...)
return pairs(self.data, ...)
end
function test:get_data()
print(self.data)
end
a = test.new()
a.data = {"asdasd"}
b = torch.serialize(a)
c = torch.deserialize(b)
print(torch.typename(c))
print(c:get_data())
This gives the expected:
test
{
1 : "asdasd"
}
Based on previous questions here I managed to create the dataset, print all recipes listed and now I am trying to pick one of the recipes from that list and show its Title, Instructions and Ingredients. The instructions are mapped to the Recipes via the pkID column and the ingredients are mapped to the Recipes through a recipeID column. When I open the database on Sqlite Database Browser I can access this information inside the Tables dropdown list, so I suppose the proper name for them are tables within the database.
I am not being able to "filter" by pkID and by recipeID, so that after picking one recipe, only the appropriate content is shown.
This is the code in Python of what I am trying to do in Genie:
def PrintSingleRecipe(self,which):
sql = 'SELECT * FROM Recipes WHERE pkID = %s' % str(which)
print '~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~'
for x in cursor.execute(sql):
recipeid =x[0]
print "Title: " + x[1]
print "Serves: " + x[2]
print "Source: " + x[3]
print '~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~'
sql = 'SELECT * FROM Ingredients WHERE RecipeID = %s' % recipeid
print 'Ingredient List:'
for x in cursor.execute(sql):
print x[1]
print ''
print 'Instructions:'
sql = 'SELECT * FROM Instructions WHERE RecipeID = %s' % recipeid
for x in cursor.execute(sql):
print x[1]
print '~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~'
resp = raw_input('Press A Key -> ')
I have not been able to improve much of my code, it seems that using the approach I used before of iterating in a step statement cannot be used here. This is how far I got in Genie:
def PrintSingleRecipe(db:Database)
stmt:Statement = PreparedStatements.select_all( db )
res:int = UserInterface.raw_input("Select a recipe -> ").to_int()
cols:int = stmt.column_count ()
var row = new dict of string, string
item:int = 1
print "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
while res == ROW
for i:int = 0 to (cols - 1)
row[ stmt.column_name( i ) ] = stmt.column_text( i )
stdout.printf( "%-5s", item.to_string( "%03i" ))
stdout.printf( "%-30s", row[ "Title" ])
stdout.printf( "%-20s", row[ "Serves" ])
stdout.printf( "%-30s\n", row[ "Source" ])
print "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
print "Ingredient list"
print " "
stdout.printf("%-5s", item.to_string( "%03i" ))
I have found a solution to the problem, maybe it can be optimized. For now it is enough.
Answers from another question helped immensely. The solution I used was to use the exec function and point the callback to the PrintSingleRecipe().
Some adjustments had to be done for it to work as a callback, but I got what I needed.
Here is the code where the function gets called:
while true
response:string = UserInterface.get_input_from_menu()
if response == "1" // Show All Recipes
PrintAllRecipes(db)
else if response is "2" // Search for a recipe
pass
else if response is "3" //Show a Recipe
res:string = UserInterface.raw_input("Select a recipe -> ")
sql:string = "SELECT * FROM Recipes WHERE pkID = " + res
db.exec(sql, PrintSingleRecipe, null)
else if response is "4"//Delete a recipe
pass
else if response is "5" //Add a recipe
pass
else if response is "6" //Print a recipe
pass
else if response is "0" //Exit
print "Goodbye"
break
else
print "Unrecognized command. Try again."
Here is how the PrintSingleRecipe looks like:
def PrintSingleRecipe(n_columns:int, values:array of string, column_names:array of string):int
print "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
for i:int = 0 to n_columns
stdout.printf ("%s = %s\n", column_names[i], values[i])
print "~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~"
print "Ingredient list"
print " "
return 0