expr-story Pub

Dates and durations

send::  msg ctx.set  (d1=now())

expect::  (d1 is Date)

send::  msg ctx.set  (x=js{{ java....)

expect::  (x is Number)

send::  msg ctx.set  (d1m=toMillis(a...)

expect::  (d1m is Number)

send::  msg ctx.set  (d1d=(d1m as Da...)

expect::  (d1d is Date)
expect::  (d1d is d1)
send::  msg ctx.set  (d1b=(d1 + "1s"...)

expect::  (d1b != d1)
expect:: NOT (d1b is d1)

send::  msg ctx.set  (d1=(d1 + "1s"...)

expect::  (d1 is Date)
send::  msg ctx.set  (d1=(now() + "...)

expect::  (d1 is Date)
send::  msg ctx.set  (d1=(d1 + "1 n...)

expect::  (d1 is Date)
send::  msg ctx.set  (d1=(d1 + "1 m...)

expect::  (d1 is Date)
send::  msg ctx.set  (d1=(d1 + "1 h...)

expect::  (d1 is Date)
send::  msg ctx.set  (d1=(d1 + "1 d...)

expect::  (d1 is Date)
send::  msg ctx.set  (d1=(d1 + "1M"...)

expect::  (d1 is Date)
send::  msg ctx.set  (d1=(d1 + "1 y...)

expect::  (d1 is Date)

send::  msg ctx.set  (d1=(now() - "..., d2=(now() + "...)

expect::  (d1 < d2)
expect:: NOT (d1 > d2)
expect::  ( (((d1 > d2)) is false))

Simple expressions

Setting a variable

ctx.set is used to set one or more variables in the current context:

send::  msg ctx.set  (res="123"="123")

expect::  (res is "123")

ctx.setVal is useful if the name is itself sourced, a variable:

send::  msg ctx.setVal  (name="res"="res", value:Number=321=321)

expect::  (res is 321)
expect::  (res is number)

ctx.echo shows all the details about the input arguments - use it to see types, values etc:

send::  msg ctx.echo  (res12="123"="123")

expect::  (res12 is "123")

Contains:

send::  msg ctx.set  (res23="123"="123")

expect::  (res23 contains "2")
expect::  (res23 containsNot "4")

encoders

send::  msg ctx.base64encode  (res29="res29"="res29")

expect::  (payload is "cmVzMjk=")

send::  msg ctx.base64decode  (res29=payload)

expect::  ( ((payload as string) is "res29"))

send::  msg ctx.sha1  (res35="res35"="res35")

expect::  (payload is "7D509433920201DF3A7EE4363970D83359D826B8")
expect::  (res35_sha1 is "7D509433920201DF3A7EE4363970D83359D826B8")

send::  msg ctx.sha256  (res35="res35"="res35")

expect::  (payload is "2e994a1eb4aea52f7c059c6b82f05f14777575371f3acf833ef72fb7e294ac71")
expect::  (res35_sha256 is "2e994a1eb4aea52f7c059c6b82f05f14777575371f3acf833ef72fb7e294ac71")

Resetting a value

This will remove a value from the context:

send::  msg ctx.setVal  (name="res"="res")

expect::  (res not defined)

Reset the entire context, with ctx.clear:

send::  msg ctx.setVal  (name="res"="res", value:Number=321=321)

expect::  (res is 321)

send::  msg ctx.clear 

expect::  (res not defined)

Constants

Examples of constants of different types:

send::  msg ctx.set  (res:Number=45=45)

expect::  (res is 45)
expect::  (res is number)

send::  msg ctx.set  (res="astra"="astra")

expect::  (res is "astra")
expect::  (res is string)

String interpolation and escaping of such

send::  msg ctx.set  (interpol="x"="x")

send::  msg ctx.set  (int1="${interpo...)

expect::  (int1 contains "x")
send::  msg ctx.set  (int1="a${interp...)

expect::  (int1 contains "x")
send::  msg ctx.set  (int1="$${interp...)

expect::  (int1 containsNot "x")
send::  msg ctx.set  (int1="a$${inter...)

expect::  (int1 containsNot "x")

Simple expressions

The usual simple expressions are available and they are type aware:

send::  msg ctx.set  (ai:Number=1=1, bi:Number=2=2)

send::  msg ctx.set  (as="1"="1", bs="2"="2")

send::  msg ctx.set  (res53=(ai + bi))

expect::  (res53 is 3)
send::  msg ctx.set  (res56=(as + bs))

expect::  (res56 is "12")

Precendence and associativity

send::  msg ctx.set  (res52:Number=(((1 - 2) ...)

expect::  (res52 is 20)

String functions

send::  msg ctx.set  (res57="1 2 3 "="1 2 3 ")

// $expect (res57:Array) expect::  (res57[="length"] is 6)
expect::  ( ((res57[="length"] + 5) is 11))
expect::  ( ((sizeOf(res57.lines) + 4) is 7))
send::  msg ctx.set  (l66=res57[="li...)

Template expansion

By default all strings are templatized in expressions, using ${...} to match a simpler expression:

send::  msg ctx.setVal  (name="template1"="template1..., value="is${1+2}")

expect::  (template1 is "is3")

Use this to configure environment settings like URLs for instance

send::  msg ctx.set  (HOST ="https://www.google.ca"...="https://w...)

send::  msg ctx.echo  (url="${HOST}/s...)

expect::  (url is "https://www.google.ca/search?q=dieselapps")
expect::  ( ("${HOST}/" is "https://www.google.ca/"))

Sourcing and checking values

send::  msg expr.source.erase 

expect::  (erased not defined)

send::  msg ctx.set  (val192="")

expect::  (val192 is defined)
expect::  (val192 not undefined)
expect::  (val192 is empty)
expect::  (val192 not nzlen)

send::  msg ctx.set  (val198:Undefined=null)

expect::  (val198 not defined)
expect::  (val198 is undefined)
expect::  (val198 is empty)
expect::  ( NOT ((val198 not empty)))
expect::  ( NOT (((val198 not empty))))
expect::  (val198 not nzlen)

send::  msg ctx.set  (val204="abcd"="abcd")

expect::  (val204 is defined)
expect::  (val204 not undefined)
expect::  (val204 not empty)
expect::  (val204 is nzlen)

The diesel object:

send::  msg ctx.set  (res5=js{{ diese...)

expect::  (res5 not empty)

send::  msg ctx.set  (res139=js{{ diese...)

expect::  (res139 not empty)

The wix object:

send::  msg ctx.set  (res144=js{{ wix.d...)

expect::  (res144 not empty)

Boolean expressions

send::  msg ctx.set  (b1:Boolean=true)

expect::  (b1 is true)
expect::  (b1 not false)
expect::  (b1)
expect::  (b1)$ifc:: true
expect::  (b1)$ifc:: b1
expect::  (b1)$ifc:: (b1 is true)
expect::  (b1)$ifc:: (b1 not false)

send::  msg expr.bool.test1 

expect::  (b2)
expect::  (b3 is true)
expect::  (b4)
expect::  (b5 not defined)

send::  msg expr.bool.test1nos 

expect::  (b2n)
expect::  (b3n is true)
expect::  (b4n)
expect::  (b5n not defined)

send::  msg expr.bool.test2  (a:Number=1=1, b:Number=2=2)

expect::  (b23)
expect::  (b26)

send::  msg expr.bool.test2  (a:Number=2=2, b:Number=1=1)

expect::  (b22)
expect::  (b25)

send::  msg expr.bool.test2  (a:Number=2=2, b:Number=2=2)

expect::  (b24)
expect::  (b25)
expect::  (b26)

send::  msg expr.bool.testAllExpr  (a:Number=1=1, bb:Number=2=2)

expect::  (b > 24)

send::  msg expr.bool.testContains  (a="123"="123")

expect::  (b94 is true)
expect::  (b95 is true)

send::  msg expr.bool.testAndUndef 

expect::  (b47 not defined)
expect::  (b48 is true)
expect::  (b49 not defined)
expect::  (b50 not defined)
expect::  (b51 is true)

send::  msg expr.bool.testBra1 

expect::  (bb105 is true)

send::  msg expr.int.lt 

Arrays, Lists and range accessors

Range accessor on Strings

send::  msg ctx.set  (l3="012345"="012345")

From index to end send::  msg ctx.set  (l4=l3[:Range=...)

expect::  (l4 is "012345")

From index toindex send::  msg ctx.set  (l8=l3[:Range=...)

expect::  (l8 is "0123")

From index to one before end (last index if negative is relative to the end) send::  msg ctx.set  (l11=l3[:Range=...)

expect::  (l11 is "01234")

Both ends relative to the end send::  msg ctx.set  (l14=l3[:Range=...)

expect::  (l14 is "34")

TODO why is this expected?

send::  msg ctx.set  (l14=l3[:Range=...)

expect::  (l14 is "45")

Range accessor on Lists

send::  msg ctx.set  (l21:Array=[0,1,2,3,4...)

send::  msg ctx.set  (l4=l21[:Range...)

expect::  (l4 is [0,1,2,3,4,5])

send::  msg ctx.set  (l8=l21[:Range...)

expect::  (l8 is [0,1,2,3])

send::  msg ctx.echo  (l11=l21[:Range...)

expect::  (l11 is [0,1,2,3,4])

send::  msg ctx.set  (l239:Array=[])

expect::  (l239 is [])

Accessor in pmatch /expect

send::  msg ctx.set  (l14=l21[:Range...)

expect::  (l14[="1"=1] is 4)

send::  msg ctx.set  (state281:JSON={source:[0...)

expect::  (state281[="source"="source"][="0"=0] == 0)

send::  msg ctx.set  (state281:JSON={source:[0...)

expect::  (state281[="source"="source"][="0"=0] is 0)

Array generators

send::  msg ctx.set  (a333:Array=[0 .. ( (9...)

expect::  ( (sizeOf(a333) == 4))

send::  msg ctx.set  (a333:Array=[0 .. 9])

expect::  ( (sizeOf(a333) == 10))

send::  msg ctx.set  (a333:Array=([0 .. 9] ...)

expect::  ( (sizeOf(a333) == 10))
expect::  (a333[="9"=9] == "9a")

Setters and accessors

send::  msg test.ctxAccessor 

expect::  (payload is ( (90 + 87) ))

json in context and array sum

send::  msg ctx.set  (state294:JSON={source:[0...)

send::  msg test.jsonAccessorSet  (source="source"="source", dest="dest"="dest", aux="aux"="aux")

expect::  (state294[="source"] is [1,2,3,4,5])
expect::  (state294[="dest"] is [0])

Expansion

val a217="a217v"="a217v" send::  msg ctx.set  (a218="${a217}")

expect::  (a218 is "a217v")

Javascript expressions

Simple javascript - script is independent (no arguments):

send::  msg ctx.set  (a225=js{{ 1+4 }...)

expect::  (a225 is 5)

Escaping quotes with javascript regex (notice a230 available inside the js expression):

val a230="{"a":32}"="{"a":32}" send::  msg ctx.set  (a231=js{{ a230....)

expect::  (a231 is "{&quot;a&quot;:32}")

More JS examples:

send::  msg ctx.set  (now=js{{ java....)

// $send ctx.set( // later=js:{var d = new Date(); d.setSeconds(d.getSeconds() + 10); return d.toISOString();} // ) send::  msg ctx.set  (later=js{{ var d...)

send::  msg ctx.set  (noweh=js{{ var d..., later=js{{ var d...)

expect::  (now is number)

Precedence

As

send::  msg ctx.set  (a=(("1234" +...)

expect::  (a is 12345)

val p15="p15"="p15" val p16=(("p16-" + p15) as "application/pdf") send::  msg ctx.echo  (a=p16)

expect::  ( (typeOf(p16) is "application/pdf"))
expect::  (p16 is "p16-p15")

as a variable

val p366="Number"="Number" send::  msg ctx.set  (a=(("1234" +...)

expect::  (a is 12345)

Filter

send::  msg ctx.set  (a:Array=([1,2,3] f...)

expect::  (a is [2,3])

send::  msg ctx.set  (a:Array=([1,2,3] f...)

expect::  (a is [1])

send::  msg ctx.set  (a:Array=([1,2,3] f...)

expect::  (a is [1,2])

send::  msg ctx.set  (a:Array=([1,2,3] f...)

expect::  (a is [2,3])

Map

send::  msg ctx.set  (a278:Array=([1,2,3] m...)

expect::  (a278 is [2,3,4])

TODO this is stuck in parm evaluation on second pass

// .orElse(cur.find(a => a.name == name && a.hasCurrentValue)) // or is it the static value? // $send ctx.set( a401 = [1,2] map (x=> expr.oper.sumnump (a=x,b=2) ) ) // $expect (a401 is [3,4])

Both filter and map

TODO these work with ExprParser1

send::  msg ctx.set  (a281:Array=(([1,2,3] ...)

expect::  (a281 is [3,4])

send::  msg ctx.set  (a284:Array=((([1,2] +...)

expect::  (a284 is [3,4])

send::  msg ctx.set  (a287:Array=(([1,2,3] ...)

expect::  (a287 is [3,4])

TODO this is not working

// $send ctx.set( a290 = [1,2,3] filter (x=> js:{(x - 1*1 + 1) > 1}) map (x=> x + 1) ) // $expect (a290 is [3,4])

Convert to string and use a JS expression for filter lambda send::  msg ctx.set  (a298:Array=(([1,2,3] ...)

send::  msg ctx.echo  (res299=(res57[="l...)

expect::  (res299 is ["1"])

Map on range

TODO implement map on range - range to be basic ttype

// $send ctx.set( a452 = 1..3 map (x=> x + 1) ) // $expect (a281 is [3,4])

Expressions in messages

send::  msg expr.oper.sumnum  (a:Number=1=1, b:Number=2=2)

expect::  (res is 3)
send::  msg expr.oper.sumnum2  (a:Number=1=1)

expect::  (res is 3)
send::  msg expr.oper.sumnum3  (a:Number=1=1)

expect::  (res is 3)

send::  msg expr.oper.sumstr  (first="Jane"="Jane", last="Doe"="Doe")

expect::  (res is "Jane Doe")

sizeOf

send::  msg ctx.set  (a358:Array=[1,2,3])

send::  msg ctx.echo  (x=sizeOf(a35...)

send::  msg ctx.echo  (x=sizeOf(y=a...)

send::  msg ctx.echo  (x=sizeOf(y=a...)

expect::  ( (sizeOf(a358) > 0))

send::  msg test.diesel.condif 

expect::  (b138 is 1)

empty is zero not exception

send::  msg ctx.set  (c507:Undefined=null)

expect::  (c507 is undefined)
send::  msg ctx.set  (c507=a358[="44"...)

expect::  (c507 is undefined)
expect::  ( (sizeOf(c507) == 0))
// With payload - this used to fail at one point // $ ctx.set(payload=null) // $expect (payload is undefined) // // // $ ctx.set(payload=a358[44]) // // // $ ctx.echo (yyz=payload) // // // $expect (payload is undefined) // // // $expect (sizeOf(payload) == 0)

Special cases

Just making sure this parsed:

send::  msg dieseltest.expr151  (env:Number=123=123)

expect::  (res151 >= 1)

Bugs

send::  msg testdiesel.bug.overwritectxname  (payload="a"="a", a="a"="a")

expect::  (payload is "z")

send::  msg testdiesel.bug.overwritectxname  (payload="a"="a", a="a"="a")

expect::  (payload is "z")

This was an issue - setting and then expanding in a submessage bug

send::  msg test.diesel.testSetExpand 

expect::  (yy is "123")

0 $mock:: test.diesel.testSetExpand
   ctx.set (YY="123"="123")
   ctx.set (yy="${YY}")
   step should have expanded by now - running a js regex to mess it up if not expanded
   step otherwise the expect will evaluate it and it works...
   . (yy=js{{ yy.replace(/$/g, "xx") }})

FUnctions

val x477:Array=[] send::  msg ctx.echo  (x472=accessor(o...)

expect::  (x472 is undefined)

Last line parse test

send::  msg testdiesel.lastline 

expect::  (payload contains "end of line is parsed here...")

MAKE SURE THERE IS NO \n after this line 0 $mock:: testdiesel.lastline
   . (payload="end of line is parsed here...")

Arrays

val query:JSON={"key": "elf"} send::  msg ctx.set  (y=(query map...)

send::  msg ctx.echo  (x=(y mkStrin...)

expect::  (x contains "elf")

setting should work the same in all scopes:

0 $mock:: z.v
   . (x=[])
   . (y=x[="0"=0])
   . (ctx[="y1"]=x[="0"=0])
   . (dieselScope[="y2"]=x[="0"=0])
   . (dieselRoot[="y3"]=x[="0"=0])
   . (dieselRealm[="y4"]=x[="0"=0])

send::  msg z.v 

expect::  (y not defined)
expect::  (y1 is undefined)
expect::  (y2 is undefined)
expect::  (y3 is undefined)
expect::  (dieselRealm[="y4"] is undefined)

0 $mock:: z.v1
   . (x=[5])
   . (y=x[="0"=0])
   . (ctx[="y1"]=x[="0"=0])
   . (dieselScope[="y2"]=x[="0"=0])
   . (dieselRoot[="y3"]=x[="0"=0])
   . (dieselRealm[="y4"]=x[="0"=0])

send::  msg z.v1 

expect::  (y is 5)
expect::  (y1 is 5)
expect::  (y2 is 5)
expect::  (y3 is 5)
expect::  (dieselRealm[="y4"] is 5)

Long int numbers

send::  msg ctx.set  (x:Number=3179699189=3179699189)

expect::  (x is number)
expect::  (x > 55)

Proper number type and others

send::  msg ctx.set  (s572=sprintf(a:...)

send::  msg ctx.set  (s573=sprintf(a:...)

send::  msg ctx.set  (s574=sprintf(a:...)

expect::  (s572 is "44")
expect::  (s573 is "44.0")
expect::  (s574 is "44.0")

Bool var ops

TODO this is not working

val x=cmp(op:String=">"=">",a:Number="1"=1,b:Number="2"=2) send::  msg ctx.echo  (x)

send::  msg ctx.echo  (y568=cmp(op:Str...)

expect::  (y568 is false)

send::  msg ctx.echo  (y568=cmp(op:Str...)

expect::  (y568 is true)

send::  msg test.diesel.boolexpr1 

expect::  (res is 2)


Was this useful?    

By: Razie | 2017-09-02 .. 2022-06-17 | Tags: story , dsl , check , sanity


Viewed 406 times ( | History | Print ) this page.

You need to log in to post a comment!

© Copyright DieselApps, 2012-2022, all rights reserved.