
//assert 0=== refcount
false || scope {
    var dest array []
    var count = 0;
    var ffObjects = proc {n} {
        assert n>0
        var i = 0
        assert 'undefined' !== this.count
        while {i<n} {
            // assert 'object' === typename [dest.push object {i:i}]
            object {i:i}
            set i i+1
            //$print i
            set count count+1
        }
    }
    
    // Function.apply is-a Function, so we can do:
    assert 'function' === typename ffObjects.apply.apply.apply


    var myScope {
        $ffObjects 35
        // $ffObjects 5
        // $ffObjects 5
        [ffObjects.apply ffObjects array [5]]
        $ffObjects 10

        $print "Created a total of" count "object(s)."        
        if{var len [dest.length]} {
            $print 'dest.length =' len // dest
        }
    }
    scope myScope

    //return

    var prototype "hi"
    assert {  hi  } === prototype
    assert 'string' === typename prototype
    // assert 10001 === catch { set prototype 8 }.code
    assert 201 === catch { set dest.prototype 1 }.code
    set dest.prototype proc {}{}
    assert 1 === refcount dest.prototype
    //return dest.prototype
    set dest.hi = array["hiiii"]
    dest.prototype /* testing for old implicit return val
                      corruption bug. */
    //dest.hi
}



1 && scope {
    var S api.string, ts S.toString
    assert '1' === [ts 1]
    assert '2.3' === [ts 2.3]
    assert 'true' === [ts true]
    assert 'false' === [ts false]
    assert 'null' === [ts null]
    assert 'undefined' === [ts undefined]
    assert 'array' === typename array{}
    assert 'object' === typename object {}
    assert 'string' === typename [ts array{}]
    assert 'string' === typename [ts object{}]
}

1 && scope {
    var obj object {b:2, c:3}
    set obj.aa 1.5
    set obj.z 10
    set obj.a 1
    set obj.(true) true
    set obj.(false) false
    assert obj.(true)
    assert !obj.(false)
    $print obj
    set obj.(true) "true"
    set obj.0 "zero"
    set obj.1 "one"
    set obj.(1.0) "one.oh"
    assert "one.oh" === obj.1
    set obj.(1.2) "one.two"
    $obj.eachProperty proc (k,v){
        $print '\t' k '=' v
    }
    true;
}

1 && scope {
    var myArray array [], myObject object {}

    set myArray.1 "a" // sets array index
    set myArray."1" "b" // sets key/value property!
    assert "a" === myArray.1
    assert "b" === myArray."1"
    set myObject.1 "a"
    set myObject.(1.0) "b" // OVERWRITES key (1).
    assert "b" === myObject.(1.0)
    assert "a" !== myObject.1
    assert "a" != myObject.1 // fails because (1==1.0) for key purposes
}

1 && scope {
    var S api.string
    assert "a43.21" === $S.concat "a" 4 3.21
    assert "hi there" === $S.toLower "Hi There"
    assert ["hi there".toUpper] === $S.toUpper "Hi There"
}

1 && scope {

    assert "123 " === ["  
123 ".trimLeft]
    assert "  123" === ["  123  

".trimRight]
    assert "123" === ["  
123  
".trim]



}

1 && scope {
    var f proc
    {a, b}
    {
        assert 3 === x
        assert b === 7
    }
    $f var x 3 7
    assert 'undefined' === typename x
}

1 && scope {
    var obj object{ a: 1, b:"two", c:"©" }
    $print '[obj.toJSONString] =' [obj.toJSONString]
    var out api.io.output
    set out.separator '\t'
    set out.eol '\n'
    $out 1 2 3 obj
    
}

1 && scope {
    const pi api.numeric.parseInt
    $print [pi "3"]
    assert 3 === [pi "3"]
    assert undefined === [pi "4.1"]
    //$print 'OK:' ex

    const pd api.numeric.parseDouble
    assert 3.2 == [pd "3.2"]
    assert -3.2 == [pd "-3.2"]
    assert undefined === [pd "-3.2x"]
}

1 && scope {
    const ob object{}
    $ob.set object {a:1, b:"bbb"}
    assert 1 === ob.a
    assert "bbb" === ob.b
    return ob.b /*
            Testing a fix for an implicit return value corruption
            bug. If it crashes during scope cleanup just after
            this operation, that's bad. Seems to be fixed,
            though.
         */
}

1 && scope {
  const s = "hi"
  assert 2 === [s.lengthBytes]
  const d = 3.2
  assert 3 === [d.toInt]
  assert 4 === ["!!!!".lengthBytes]
  assert 304 === catch {s.toInt = 0}.code
  assert 7 === [7.0.toInt]
__sweep
  assert 1 == [1.5.floor]
  assert 2 == [1.5.ceil]
  assert -1 == [(-0.5).floor]
  assert 0 == [(-0.5).ceil]

__sweep
  const str "abc"
  assert 'b' === [str.charAt 1]
  assert 98 === [str.charAt 1 true]
  assert undefined === [str.charAt 3]

__sweep
  const ustr "äbä"
  assert "ä" ===[ustr.charAt 0]
  assert 0xe4 === [ustr.charAt 0 true]
  assert 3 === [ustr.lengthUtf8]
  assert 5 === [ustr.lengthBytes]
  assert 201 === catch{[ustr.charAt]}.code
  $print 'ustr =' ustr
}


1 && scope {
    const b [api.string.Buffer 100]
    $print 'buffer:' b
    assert 100 <= [b.capacity]
    assert 0 === [b.length]
    [b.append object{x:"hi!"} ', ' array[3,4,5]]
    assert 0 < [b.length]
    $print '[b.toString] =' [b.toString]
    $print '[b.toString 0 2] = <<<' [b.toString 0 2] '>>>'
    $print '[b.toString 4] = <<<' [b.toString 4] '>>>'
__sweep
    [b.reset]
    assert 0 === [b.length]
    assert 0 < [b.capacity]
    assert [b.capacity 0]
    assert 0 === [b.capacity]
    assert 0 === [b.length]
    assert [b.byteAt 8 42]
    assert 42 === [b.byteAt 8]
    assert 0 === [b.byteAt 7]
    [[b.reset].readFile __FILE]
    assert 500 < [b.length]
}

1 && scope {
    const b = [api.string.Buffer]
    [b.length 20]
    [b.fill '$']
    assert 36 === [b.byteAt 0]
    assert 36 === [b.byteAt 19]
    [b.fill '!' 1 18]
    assert 36 === [b.byteAt 0]
    assert 36 === [b.byteAt 19]
    assert 33 === [b.byteAt 1]
    assert 33 === [b.byteAt 18]
    assert '$!' === [b.toString 0 2]
}


1 && scope {
  var d = 3.2
  d.prototype.two = proc{}{
    return this * 2;
  }
  //$print 'd.prototype =' d.prototype
  assert 6.4 === [d.two]
  assert 304 === catch{d.prototype = object{}}.code
  assert 4.0 === [2.0.two]
  assert 6.2 === [3.1.two]
  assert 8 == [(2.0*2).two]

  1.prototype.two = 0.0.two
  assert 2 === [1.two]
  assert -8 === [(-4).two]
  assert 3.0 === [3.toDouble]
}

1 && scope {
    const a array[1,2,3]
    assert 3 === [a.length]
    assert 1 === [a.shift]
    assert 1 === refcount a.0
    assert 0 === refcount [a.shift]
    assert 1 === [a.length]
    assert 3 === [a.shift]
    assert undefined === [a.shift]
    assert 7 === [a.unshift 7]
    assert 1 === [a.length]
}

1 && scope{ /* Testing the nuances of String.split()... */

    const split = proc(s,sep){
        sep = sep || ':'
        var ar = s.split(sep)
        var j = ar.join(sep)
        //print(s, ar, ar.join(sep))
        assert j === s
        return ar
    }


    1 && scope {
        var str = "//aaa//b//c//xy//"
        var sep = '//'
        var ar = [split str sep]
        //[print ar]
        assert [ar.join sep] === str
        assert undefined == ar.0
        assert undefined === ar.5
        assert 6 === [ar.length]
        assert 'aaa' === ar.1
        assert 'xy' === ar.4
    }

    1 && scope {
        var str = "aaa/b/c/xy/"
        var sep = '/'
        var ar = [split str sep]
        //[print ar]
        assert [ar.join sep] === str
        assert 5 === [ar.length]
        assert 'aaa' === ar.0
        assert undefined === ar.4
    }

    1 && scope {
        var str = "aaa©b©c©"
        var sep = '©'
        var ar = [split str sep]
        //[print ar]
        assert [ar.join sep] === str
        assert 4 === [ar.length]
        assert 'aaa' === ar.0
        assert undefined === ar.3
    }

    1 && scope{
        var str = ":::"
        var sep = ':'
        var ar = [split str ':']
        //[print ar]
        assert [ar.join sep] === str
        assert 4 === [ar.length]
        assert !ar.0
        assert !ar.3

    }

    1 && scope {
        var str = ":"
        var sep = str
        var ar = [split str sep]
        assert [ar.join sep] === str
        assert 2 === [ar.length]
        assert !ar.0
        assert !ar.1
    }

    1 && scope {
        var ar = [split ":a:b:" ':']
        assert 4 === [ar.length]
        assert !ar.0
        assert 'a' === ar.1
        assert 'b' === ar.2
        assert !ar.3
    }

    1 && scope {
        var ar = [split "abc" '|']
        assert 1 === [ar.length]
        assert 'abc' === ar.0
    }

    1 && scope {
        var ar = [split "" '.']
        assert 1 === [ar.length]
        assert "" === ar.0
    }

    1 && scope {
        var ar = [split "a:::b" ':']
        assert 4 === [ar.length]
        assert "a" === ar.0
        assert !ar.1
        assert !ar.2
        assert "b" === ar.3
    }
}


var end {You have reached the end of script #8.}
return ([print end], end)
