/* String method tests... */

scope{
  assert 'ab' === 'a'.concat('b');
  assert 'ABC' === 'a'.concat('b','c').toUpper();
  assert 42 === '0*'.byteAt(1);
  assert undefined === '0'.byteAt(3);
  assert '*' === '1*1'.charAt(1);
  assert '☺' === '1☺1'.charAt(1);
}

scope {
    assert 'Z☺Z' === 'z☺z'.toUpper();
    assert 'z☺z' === 'Z☺Z'.toLower();

    var str = '↻Æ©';
    assert 5 === "©123©".length();
    assert 7 === "©123©".lengthBytes();
    assert 3 === str.length();
    assert 7 === str.lengthBytes();
    assert '↻' === str.charAt(0);
    assert 'Æ' === str.charAt(1);
    assert '©' === str.charAt(2);
    assert undefined === str.charAt(3);
    assert 'Æ©' === str.substr(1);
    assert '↻Æ' === str.substr(0,2);

    
    str = 'こんにちは' /*no idea what this says (or not) - copied it from the net.
                        Google says it means "Hi there"*/;
    assert 15 === str.lengthBytes();
    assert 5 === str.length();
    assert 'こ' === str.charAt(0);
    assert 'ん' === str.charAt(1);
    assert 'に' === str.charAt(2);
    assert 'ち' === str.charAt(3);
    assert 'は' === str.charAt(4);
    assert 'んにち' === str.substr(1,3);
};


scope {
  /* The subtleties of split()... */
  const split = proc(s,sep){
    sep || (sep = ':');
    var ar = s.split(sep);
    var j = ar.join(sep);
    assert j === s;
    return ar;
  };

  scope {
    var str = "//aaa//b//c//xy//";
    var sep = '//';
    var ar = split(str,sep);
    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;
  }

  scope {
    var str = "aaa/b/c/xy/";
    var sep = '/';
    var ar = split(str, sep);
    assert ar.join(sep) === str;
    assert 5 === ar.length();
    assert 'aaa' === ar.0;
    assert undefined === ar.4;
 }

  scope {
    var str = "aaa©b©c©";
    var sep = '©';
    var ar = split(str, sep);
    assert ar.join(sep) === str;
    assert 4 === ar.length();
    assert 'aaa' === ar.0;
    assert undefined === ar.3;
  }

  scope{
    var str = ":::";
    var sep = ':';
    var ar = split(str, ':');
    assert ar.join(sep) === str;
    assert 4 === ar.length();
    assert !ar.0;
    assert !ar.3;
  }

  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;
  }

  scope {
    var ar = split(":a:b:",':');
    assert 4 === ar.length();
    assert !ar.0;
    assert 'a' === ar.1;
    assert 'b' === ar.2;
    assert !ar.3;
  }

  scope {
    var ar = split("abc", '|');
    assert 1 === ar.length();
    assert 'abc' === ar.0;
  }

  scope {
    var ar = split("", '.');
    assert 1 === ar.length();
    assert "" === ar.0;
  }

  scope {
    var ar = split("a:::b", ':');
    assert 4 === ar.length();
    assert "a" === ar.0;
    assert !ar.1;
    assert !ar.2;
    assert "b" === ar.3;
  }

} /* end split() */

scope {
  //assert "3.00.1" === "3.00.1" /* just making sure */;
  //print("3.00.1", "3.0"+0.1);
  assert "3.00.1" === "3.0"+0.1; // string on the left
  assert 3.7 === 0.7 + "3"; // string on the right
  assert 3.74 === 0.7 + "3" + "0.04";
  assert 3.1 === 3.1 + "abc"; // "abc"==0
  assert 5 === +"5";
  assert -5 === -"5";
  assert -5 === +"-5";
  assert 1.2 === -"-1.2"; // but beware of precision changes on such conversions!
}

scope {
  const sp = "".prototype;
  sp.firstChar = proc(asInteger=false){
    return this.charAt(0, asInteger);
  };
  assert "a" === "abc".firstChar();
  //unset "".prototype.firstChar; // hmmm - unset cannot deal with this.
  unset sp.firstChar;
}

scope {
    var a = "a";
    a += "b";
    assert 'ab' === a;
}
