go.ketch.com/lib/goja@v0.0.1/string_test.go (about) 1 package goja 2 3 import ( 4 "strings" 5 "testing" 6 "unicode/utf16" 7 ) 8 9 func TestStringOOBProperties(t *testing.T) { 10 const SCRIPT = ` 11 var string = new String("str"); 12 13 string[4] = 1; 14 string[4]; 15 ` 16 17 testScript(SCRIPT, valueInt(1), t) 18 } 19 20 func TestImportedString(t *testing.T) { 21 vm := New() 22 23 testUnaryOp := func(a, expr string, result interface{}, t *testing.T) { 24 v, err := vm.RunString("a => " + expr) 25 if err != nil { 26 t.Fatal(err) 27 } 28 var fn func(a Value) (Value, error) 29 err = vm.ExportTo(v, &fn) 30 if err != nil { 31 t.Fatal(err) 32 } 33 for _, aa := range []Value{newStringValue(a), vm.ToValue(a)} { 34 res, err := fn(aa) 35 if err != nil { 36 t.Fatal(err) 37 } 38 if res.Export() != result { 39 t.Fatalf("%s, a:%v(%T). expected: %v, actual: %v", expr, aa, aa, result, res) 40 } 41 } 42 } 43 44 testBinaryOp := func(a, b, expr string, result interface{}, t *testing.T) { 45 v, err := vm.RunString("(a, b) => " + expr) 46 if err != nil { 47 t.Fatal(err) 48 } 49 var fn func(a, b Value) (Value, error) 50 err = vm.ExportTo(v, &fn) 51 if err != nil { 52 t.Fatal(err) 53 } 54 for _, aa := range []Value{newStringValue(a), vm.ToValue(a)} { 55 for _, bb := range []Value{newStringValue(b), vm.ToValue(b)} { 56 res, err := fn(aa, bb) 57 if err != nil { 58 t.Fatal(err) 59 } 60 if res.Export() != result { 61 t.Fatalf("%s, a:%v(%T), b:%v(%T). expected: %v, actual: %v", expr, aa, aa, bb, bb, result, res) 62 } 63 } 64 } 65 } 66 67 strs := []string{"shortAscii", "longlongAscii1234567890123456789", "short юникод", "long юникод 1234567890 юникод \U0001F600", "юникод", "Ascii", "long", "код"} 68 indexOfResults := [][]int{ 69 /* 70 const strs = ["shortAscii", "longlongAscii1234567890123456789", "short юникод", "long юникод 1234567890 юникод \u{1F600}", "юникод", "Ascii", "long", "код"]; 71 72 strs.forEach(a => { 73 console.log("{", strs.map(b => a.indexOf(b)).join(", "), "},"); 74 }); 75 */ 76 {0, -1, -1, -1, -1, 5, -1, -1}, 77 {-1, 0, -1, -1, -1, 8, 0, -1}, 78 {-1, -1, 0, -1, 6, -1, -1, 9}, 79 {-1, -1, -1, 0, 5, -1, 0, 8}, 80 {-1, -1, -1, -1, 0, -1, -1, 3}, 81 {-1, -1, -1, -1, -1, 0, -1, -1}, 82 {-1, -1, -1, -1, -1, -1, 0, -1}, 83 {-1, -1, -1, -1, -1, -1, -1, 0}, 84 } 85 86 lastIndexOfResults := [][]int{ 87 /* 88 strs.forEach(a => { 89 console.log("{", strs.map(b => a.lastIndexOf(b)).join(", "), "},"); 90 }); 91 */ 92 {0, -1, -1, -1, -1, 5, -1, -1}, 93 {-1, 0, -1, -1, -1, 8, 4, -1}, 94 {-1, -1, 0, -1, 6, -1, -1, 9}, 95 {-1, -1, -1, 0, 23, -1, 0, 26}, 96 {-1, -1, -1, -1, 0, -1, -1, 3}, 97 {-1, -1, -1, -1, -1, 0, -1, -1}, 98 {-1, -1, -1, -1, -1, -1, 0, -1}, 99 {-1, -1, -1, -1, -1, -1, -1, 0}, 100 } 101 102 pad := func(s, p string, n int, start bool) string { 103 if n == 0 { 104 return s 105 } 106 if p == "" { 107 p = " " 108 } 109 var b strings.Builder 110 ss := utf16.Encode([]rune(s)) 111 b.Grow(n) 112 n -= len(ss) 113 if !start { 114 b.WriteString(s) 115 } 116 if n > 0 { 117 pp := utf16.Encode([]rune(p)) 118 for n > 0 { 119 if n > len(pp) { 120 b.WriteString(p) 121 n -= len(pp) 122 } else { 123 b.WriteString(string(utf16.Decode(pp[:n]))) 124 n = 0 125 } 126 } 127 } 128 if start { 129 b.WriteString(s) 130 } 131 return b.String() 132 } 133 134 for i, a := range strs { 135 testUnaryOp(a, "JSON.parse(JSON.stringify(a))", a, t) 136 testUnaryOp(a, "a.length", int64(len(utf16.Encode([]rune(a)))), t) 137 for j, b := range strs { 138 testBinaryOp(a, b, "a === b", a == b, t) 139 testBinaryOp(a, b, "a == b", a == b, t) 140 testBinaryOp(a, b, "a + b", a+b, t) 141 testBinaryOp(a, b, "a > b", strings.Compare(a, b) > 0, t) 142 testBinaryOp(a, b, "`A${a}B${b}C`", "A"+a+"B"+b+"C", t) 143 testBinaryOp(a, b, "a.indexOf(b)", int64(indexOfResults[i][j]), t) 144 testBinaryOp(a, b, "a.lastIndexOf(b)", int64(lastIndexOfResults[i][j]), t) 145 testBinaryOp(a, b, "a.padStart(32, b)", pad(a, b, 32, true), t) 146 testBinaryOp(a, b, "a.padEnd(32, b)", pad(a, b, 32, false), t) 147 testBinaryOp(a, b, "a.replace(b, '')", strings.Replace(a, b, "", 1), t) 148 } 149 } 150 } 151 152 func BenchmarkASCIIConcat(b *testing.B) { 153 vm := New() 154 155 b.ResetTimer() 156 b.ReportAllocs() 157 for i := 0; i < b.N; i++ { 158 _, err := vm.RunString(`{let result = "ab"; 159 for (let i = 0 ; i < 10;i++) { 160 result += result; 161 }}`) 162 if err != nil { 163 b.Fatalf("Unexpected errors %s", err) 164 } 165 } 166 }