
object Operators

inherit list
  Harness

Execute promise




  @Test 'initialized', task
    set a to blank
    set b to a.1 initialized 'frog'
    return b is 'frog' and a.1 is 'frog'
  
  

  // returns true for odd iterations, undefined for even including 0
  set OddTrue to process
    local i to 0
    while true
      yield i%2 ?? true :: undefined
      inc i

  set Odds to process
    local i to 1
    while true
      yield i
      set i + 2

  // returns Fibbonaci sequence
  set Fibb to process
    local
      a to 1
      b to 0
      c to 0
    while true
      set 
        c to a+b
        a to b
        b to c
      yield c


  @Test 'lop or multi inline', task
    set t to or 0,2,0
    set f to or 0,0,0
    return t is 2 and not f
    
  @Test 'lop or multi colon', task
    set t to or: 0,2,0
    set f to or: 0,0,0
    return t is 2 and not f
    
    
  @Test 'nested lop', task
    return and:
      4
      or 8, 0, or:
        0
        0
        3
      nor 0, null
      nand 2,3,0
      and 'frog', 'winter', 88
        
    
  @Test 'lop or multi block', task
    set t to or:
      0
      2
      0
    set f to or:
      0
      0
      0
    return t is 2 and not f

  @Test 'lop and multi inline', task
    set t to and 1,2,5
    set f to and 0,0,0
    return t and not f
    
  @Test 'lop nand multi inline', task
    set t to nand 1,0,5
    set f to nand 1,1,3
    return t and not f
    
  @Test 'lop nor multi inline', task
    set t to nor 0,0,0
    set f to nor 0,5,0
    return t and not f





  @Test '?', task
    set a to undefined
    try
      set b to ?a.a.a 
    catch
      return false
    return true
    
  @Test '? unused', task
    set a to undefined
    try
      set b to a.a.a 
    catch
      return true
    return false
    
  @Match '+', 5, task
    return 3 + 2

  @Match '-', 1, task
    return 4 - 3

  @Match 'binary or', 7, task
    return 5 orb 3 

  @Match 'binary and', 1, task
    return 5 andb 3 

  @Match 'binary xor', 6, task
    return 5 xorb 3 

  @Match '*', 6, task
    return 2 * 3

  @Match '/', 3, task
    return 6 / 2

  @Match '%', 1, task
    return 6 % 5

  @Match '**', 9, task
    return 3 ** 2
    
  @Match 'unary -', 3, task
    return 1 - -2
    
  @Match 'unary binary not', -8, task
    return notb 7

  @Match 'unary not', false, task
    return not true
    
  @Match 'number valid', 10, task
    return number '10'

  @Match 'number invalid', 0, task
    return number 'frog'
    
  @Test 'exists', task
    return exists false
    
  @Test 'and', task
    return 1 and 1

  @Test 'or', task
    return 0 or 1
    
  @Test 'xor', task
    return not ((1 xor 1) or (0 xor 0)) and (0 xor 1) and (1 xor 0) 

  @Test 'nand', task
    return (0 nand 0) and (0 nand 1) and (1 nand 0) and not (1 nand 1) 

  @Test 'nor', task
    return (0 nor 0) and not (0 nor 1) and not (1 nor 0) and not (1 nor 1) 

  @Test '=', task
    return 7 = 7

  @Test '>=', task
    return (1 >= 0) and (1 >= 1) 

  @Test '>', task
    return (1 > 0) and not (1 > 1)

  @Test '<', task
    return (0 < 1) and not (1 < 1) 

  @Test '<=', task
    return (0 <= 1) and (1 <= 1)

  @Test '<>', task
    return (1 <> 0) 

  @Match '?<', 2, task
    return 2 ?< 3

  @Match '?>', 3, task
    return 2 ?> 3

  @Test 'is undef', task
    return undefined is undefined

  @Test 'is obj', task
    set a to: d 1, e 2
    set b to a
    return (a is b) and (b.d=1) and (b.e=2)
    
  @Test 'isnt', task
    return 0 isnt false
  
  @Test 'isnan', task
    return not isNaN(0) and isNaN('frog')
  
  @Test 'copy', task
    set a to: d 1, e 2
    set b to a
    set c to copy a
    return (a is b) and (a isnt c) and (c.d=1) and (c.e=2)
    
  @Test 'copy value', task
    set a to copy 1 
    return a is 1
    
    
  @Test 'keys comp undefined', task
    set a to undefined|keys
    return ~Array.isArray(a) and (a.length = 0)
  
  @Test 'keys comp value', task 
    set a to 1|keys
    return ~Array.isArray(a) and (a.length=0)
  
  @Test 'keys comp list', task 
    set a to: 1, 2;|keys
    return ~Array.isArray(a) and (a.length=2) and (a.0=0) and (a.1=1)
    
  @Test 'keys comp traits', task
    set a to: a 1, b 2;|keys
    return ~Array.isArray(a) and (a.length=2) and (a.0='a') and (a.1='b')

  @Test 'keys comp iterable', task
    set a to (list a,b; |iterate)|keys
    return ~Array.isArray(a) and (a.length=2) and (a.0='0') and (a.1='1')




//  @Test 'keys unary undefined', task
//    set a to|keys undefined
//    return ~Array.isArray(a) and (a.length = 0)
  
//  @Test 'keys unary value', task 
//    set a to|keys 1
//    return ~Array.isArray(a) and (a.length=0)
  
//  @Test 'keys unary list', task 
//    set a to|keys: 1, 2
//    return ~Array.isArray(a) and (a.length=2) and (a.0=0) and (a.1=1)
    
//  @Test 'keys unary traits', task
//    set a to|keys: a 1, b 2
//    return ~Array.isArray(a) and (a.length=2) and (a.0='a') and (a.1='b')
    
  @Test 'values comp undefined', task
    set a to undefined|values
    return ~Array.isArray(a) and (a.length is 0)
    
  @Test 'values comp value', task
    set a to 1|values
    return ~Array.isArray(a) and (a.0=1)
    
  @Test 'values comp list', task
    set b to: 1, 2
    set a to b|values
    set b.0 to 3
    return ~Array.isArray(a) and (a.length=2) and (a.0=1) and (a.1=2)
    
  @Test 'values comp traits', task
    set a to: a 1, b 2;|values
    return ~Array.isArray(a) and (a.length=2) and (a.0=1) and (a.1=2)

  @Test 'values comp iterable', task
    set a to (list 1,2; |iterate)|values
    return ~Array.isArray(a) and (a.length=2) and (a.0=1) and (a.1=2)


  @Match 'delete array undefined', 5, task
    set a to: 0, 1, 2, 3, 4
    set a to self |delete undefined
    return a.length
    
  @Test 'delete array value', task
    set a to: 0, 1, 2, 3, 4
    set a to self |delete 1
    return a.length=4 and a.0=0 and a.1=2
    
  @Test 'delete array list asc', task
    set a to: 0, 1, 2, 3, 4
    set a to self |delete: 1, 2
    return a.length=3 and a.0=0 and a.1=2 and a.2=4

  @Test 'delete array list desc', task
    set a to: 0, 1, 2, 3, 4
    set a to self |delete: 2, 1
    return a.length=3 and a.0=0 and a.1=3 and a.2=4

  @Test 'delete array fields', task
    set a to: 0, 1, 2, 3, 4
    set a to self |delete traits '1' 2
    return a.length=4 and a.0=0 and a.1=2
    
  @Test 'delete array iterator', task
    set a to: 0, 1, 2, 3, 4
    set a to self |delete ((list 1, 2) |iterate)
    return a.length=3 and a.0=0 and a.1=2 and a.2=4

//  @Test 'delete array iterator', task
    
  @Test 'update undef', task
    set a to undefined
    set b to a |update: b 3, c 4
    return b.b=3 and b.c=4

  @Test 'update inappropriate', task
    try
      set a to 1 |update: 1, 2, 3
    catch
      try
        set a to: 1, 2, 3; |update 1
      catch
        return true
    return false

  @Test 'update static', task
    set a to traits a 1, b 2
    set b to a |update traits b 3, c 4
    return b.a=1 and b.b=3 and b.c=4
    
  @Test 'update dynamic left', task
    set a to list 1,2,3,4; |iterate
    set b to a |update traits '1' 'a', '3' 'b'; |collect
    return b[0]=1 and b[1]='a' and b[2]=3 and b[3]='b'
    
  @Test 'update dynamic right', task
    set a to list 1,2,3,4
    set b to a |update OddTrue() | limit 4 | collect
    return b[0]=1 and b[1]=true and b[2]=3 and b[3]=true
    
  @Test 'update dynamic both', task
    set b to (list 1,2,3,4; |iterate) |update (OddTrue() |limit 4) | collect
    return b[0]=1 and b[1]=true and b[2]=3 and b[3]=true

  @Test 'select invalid', task
    try
      set a to 1 |select 2
    catch
      return true
    return false
    
  @Test 'select array value', task
    set a to list a,b,c,d
    set c to a |select 1
    return c.length=1 and c.0='b' 
    
  @Test 'select array array', task
    set a to list a,b,c,d
    set b to: 1,3
    set c to a |select b
    return c.length=2 and c.0='b' and c.1='d'
    
  @Test 'select array iterable', task
    set a to list a,b,c,d
    set b to: 1,3; |iterate
    set c to (a |select b) |collect
    return c.length=2 and c.0='b' and c.1='d'
    
  @Test 'select array traits', task
    set a to list a,b,c,d
    set b to traits '1' a,'3' b
    set c to (a |select b)
    return c.length=2 and c.0='b' and c.1='d'
  
  @Test 'select iterable iterable', task
    set a from Fibb
    set b from Odds |limit 2,2
    set c to (a |select b) |collect
    return c.length=2 and c.0=8 and c.1=21
  
  @Test 'select iterable iterable |limited ', task
    set a from Fibb |limit 8
    set b from Odds |limit 2,3
    set c to (a |select b) |collect
    return c.length=3 and c.0=8 and c.1=21 and c.2 is undefined
  
  @Test 'select iterable array', task
    set a from Fibb 
    set b to list 7,5
    set c to (a |select b) |collect
    return c.length=2 and c.0=21 and c.1=8
  
  @Test 'select iterable array |limited', task
    set a from Fibb |limit 6
    set b to list 5,2,7
    set c to (a |select b) |collect
    return c.length=3 and c.0=8 and c.1=2 and c.2 is undefined
  
  @Test 'select iterable traits', task
    set a from Fibb
    set b to traits '7' a,'5' b
    set c to (a |select b) |collect
    return c.length=2 and (c.0=8 and c.1=21) 
    
  @Test 'select traits iterable', task
    set a to traits '1' a, '2' b, '3' c, '4' d, '5' e, '6' f, '7' g, '8' h, '9' i
    set b from Odds |limit 2,2
    set c to (a |select b) |collect
    return c.length=2 and c.0='e' and c.1='g'
  
  @Test 'select traits undefined', task
    set a to traits a 1, b 2, c 3
    set b to a |select undefined
    return b is undefined

  @Test 'select traits value', task
    set a to traits a 1, b 2, c 3
    set b to a |select 'b'
    return b.a is undefined and b.b=2 and b.c is undefined

  @Test 'select traits list', task
    set a to traits a 1, b 2, c 3
    set b to a |select list a, c
    return b.a=1 and b.c=3 and b.b is undefined

  @Test 'select traits traits', task
    set a to traits a 1, b 2, c 3
    set b to a |select traits a 1, c 2
    return b.a=1 and b.c=3 and b.b is undefined

  @Test 'collect undef', task
    set a to undefined |collect
    return a is undefined

  @Test 'generator |collect', task
    set gen3 to process 
      count 3
        yield counter
    set a to gen3 |collect
    return a.length is 3 and a.2 is 2 

  @Test 'select generator ', task
    set gen3 to process 
      count 3
        yield counter
    set a to gen3 |select: 1
    set a self |collect
    return a.length is 1 and a.0 is 1 

  @Test 'default unset', task
    return undefined default true

  @Test 'default set', task
    return not (false default true)

  @Match 'compare less', -1, task
    return 0 <=> 1
    
  @Match 'compare eq', 0, task
    return 1 <=> 1
    
  @Match 'compare greater', 1, task
    return 2 <=> 1
    
  @Match 'lsh', 2, task
    return 1 << 1
    
  @Match 'rsh', 1, task
    return 2 >> 1
    
  @Match 'rshz', 1073741821, task
    return -9 >>> 2
    
  @Match 'lsh2', 2, task
    return 1 lsh 1
    
  @Match 'rsh2', 1, task
    return 2 rsh 1
    
  @Match 'rshz2', 1073741821, task
    return -9 ursh 2
    
  @Match 'typeof', 'object', task
    return typeof @

  @Match 'isa', 'Operators', task
    return @isa
    
  @Match 'chain comp', 2, task
    return chain 2
      |by it
      
  @Match 'chain method', 1, task
    set a to: 2, 1;
    set b chain a
      sort
    return b[0]
      
  @Match 'chain persist', 2, task
    set a to: 1, 2;
    return chain a
      reverse
      |first
  
  
  @Match '... comp', 2, task
    return 2...
      |by it
      
  @Match '... method', 1, task
    set a to: 2, 1;
    set b a...
      sort
    return b[0]
      
  @Match '... persist', 2, task
    set a to: 1, 2;
    return a...
      reverse
      |first
  
  
  
  @Test 'expects 1', task
    set b to: a 1, b 2
    set a to b | expects: #a, #b, #c
    return a.length=1 and a.0.trait='c' and a.0.expects=true and a.0.found='missing'

  @Test 'expects 2', task
    set b to: a 1, b 'cat'
    set a to b | expects traits a number, b string
    return a.length=0
  
  resolve
  