123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194 |
- package goja
- import (
- "strings"
- "testing"
- "unicode/utf16"
- )
- func TestStringOOBProperties(t *testing.T) {
- const SCRIPT = `
- var string = new String("str");
-
- string[4] = 1;
- string[4];
- `
- testScript(SCRIPT, valueInt(1), t)
- }
- func TestImportedString(t *testing.T) {
- vm := New()
- testUnaryOp := func(a, expr string, result interface{}, t *testing.T) {
- v, err := vm.RunString("a => " + expr)
- if err != nil {
- t.Fatal(err)
- }
- var fn func(a Value) (Value, error)
- err = vm.ExportTo(v, &fn)
- if err != nil {
- t.Fatal(err)
- }
- for _, aa := range []Value{newStringValue(a), vm.ToValue(a)} {
- res, err := fn(aa)
- if err != nil {
- t.Fatal(err)
- }
- if res.Export() != result {
- t.Fatalf("%s, a:%v(%T). expected: %v, actual: %v", expr, aa, aa, result, res)
- }
- }
- }
- testBinaryOp := func(a, b, expr string, result interface{}, t *testing.T) {
- v, err := vm.RunString("(a, b) => " + expr)
- if err != nil {
- t.Fatal(err)
- }
- var fn func(a, b Value) (Value, error)
- err = vm.ExportTo(v, &fn)
- if err != nil {
- t.Fatal(err)
- }
- for _, aa := range []Value{newStringValue(a), vm.ToValue(a)} {
- for _, bb := range []Value{newStringValue(b), vm.ToValue(b)} {
- res, err := fn(aa, bb)
- if err != nil {
- t.Fatal(err)
- }
- if res.Export() != result {
- t.Fatalf("%s, a:%v(%T), b:%v(%T). expected: %v, actual: %v", expr, aa, aa, bb, bb, result, res)
- }
- }
- }
- }
- strs := []string{"shortAscii", "longlongAscii1234567890123456789", "short юникод", "long юникод 1234567890 юникод \U0001F600", "юникод", "Ascii", "long", "код"}
- indexOfResults := [][]int{
- /*
- const strs = ["shortAscii", "longlongAscii1234567890123456789", "short юникод", "long юникод 1234567890 юникод \u{1F600}", "юникод", "Ascii", "long", "код"];
- strs.forEach(a => {
- console.log("{", strs.map(b => a.indexOf(b)).join(", "), "},");
- });
- */
- {0, -1, -1, -1, -1, 5, -1, -1},
- {-1, 0, -1, -1, -1, 8, 0, -1},
- {-1, -1, 0, -1, 6, -1, -1, 9},
- {-1, -1, -1, 0, 5, -1, 0, 8},
- {-1, -1, -1, -1, 0, -1, -1, 3},
- {-1, -1, -1, -1, -1, 0, -1, -1},
- {-1, -1, -1, -1, -1, -1, 0, -1},
- {-1, -1, -1, -1, -1, -1, -1, 0},
- }
- lastIndexOfResults := [][]int{
- /*
- strs.forEach(a => {
- console.log("{", strs.map(b => a.lastIndexOf(b)).join(", "), "},");
- });
- */
- {0, -1, -1, -1, -1, 5, -1, -1},
- {-1, 0, -1, -1, -1, 8, 4, -1},
- {-1, -1, 0, -1, 6, -1, -1, 9},
- {-1, -1, -1, 0, 23, -1, 0, 26},
- {-1, -1, -1, -1, 0, -1, -1, 3},
- {-1, -1, -1, -1, -1, 0, -1, -1},
- {-1, -1, -1, -1, -1, -1, 0, -1},
- {-1, -1, -1, -1, -1, -1, -1, 0},
- }
- pad := func(s, p string, n int, start bool) string {
- if n == 0 {
- return s
- }
- if p == "" {
- p = " "
- }
- var b strings.Builder
- ss := utf16.Encode([]rune(s))
- b.Grow(n)
- n -= len(ss)
- if !start {
- b.WriteString(s)
- }
- if n > 0 {
- pp := utf16.Encode([]rune(p))
- for n > 0 {
- if n > len(pp) {
- b.WriteString(p)
- n -= len(pp)
- } else {
- b.WriteString(string(utf16.Decode(pp[:n])))
- n = 0
- }
- }
- }
- if start {
- b.WriteString(s)
- }
- return b.String()
- }
- for i, a := range strs {
- testUnaryOp(a, "JSON.parse(JSON.stringify(a))", a, t)
- testUnaryOp(a, "a.length", int64(len(utf16.Encode([]rune(a)))), t)
- for j, b := range strs {
- testBinaryOp(a, b, "a === b", a == b, t)
- testBinaryOp(a, b, "a == b", a == b, t)
- testBinaryOp(a, b, "a + b", a+b, t)
- testBinaryOp(a, b, "a > b", strings.Compare(a, b) > 0, t)
- testBinaryOp(a, b, "`A${a}B${b}C`", "A"+a+"B"+b+"C", t)
- testBinaryOp(a, b, "a.indexOf(b)", int64(indexOfResults[i][j]), t)
- testBinaryOp(a, b, "a.lastIndexOf(b)", int64(lastIndexOfResults[i][j]), t)
- testBinaryOp(a, b, "a.padStart(32, b)", pad(a, b, 32, true), t)
- testBinaryOp(a, b, "a.padEnd(32, b)", pad(a, b, 32, false), t)
- testBinaryOp(a, b, "a.replace(b, '')", strings.Replace(a, b, "", 1), t)
- }
- }
- }
- func TestStringFromUTF16(t *testing.T) {
- s := StringFromUTF16([]uint16{})
- if s.Length() != 0 || !s.SameAs(asciiString("")) {
- t.Fatal(s)
- }
- s = StringFromUTF16([]uint16{0xD800})
- if s.Length() != 1 || s.CharAt(0) != 0xD800 {
- t.Fatal(s)
- }
- s = StringFromUTF16([]uint16{'A', 'B'})
- if !s.SameAs(asciiString("AB")) {
- t.Fatal(s)
- }
- }
- func TestStringBuilder(t *testing.T) {
- t.Run("writeUTF8String-switch", func(t *testing.T) {
- var sb StringBuilder
- sb.WriteUTF8String("Head")
- sb.WriteUTF8String("1ábc")
- if res := sb.String().String(); res != "Head1ábc" {
- t.Fatal(res)
- }
- })
- }
- func BenchmarkASCIIConcat(b *testing.B) {
- vm := New()
- b.ResetTimer()
- b.ReportAllocs()
- for i := 0; i < b.N; i++ {
- _, err := vm.RunString(`{let result = "ab";
- for (let i = 0 ; i < 10;i++) {
- result += result;
- }}`)
- if err != nil {
- b.Fatalf("Unexpected errors %s", err)
- }
- }
- }
|