mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
js: add more tests to builtin/js and implement more builtin functions (#12049)
This commit is contained in:
parent
129c81f34d
commit
9145cd66ec
@ -194,13 +194,6 @@ pub fn (mut a array) insert_many(i int, val voidptr, size int) {
|
||||
#a.val.arr.arr.splice(i,0,...val.arr.slice(0,+size))
|
||||
}
|
||||
|
||||
pub fn (mut a array) join(separator string) string {
|
||||
mut res := ''
|
||||
#res = new string(a.val.arr.arr.join(separator +''));
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
fn (mut a array) push(val voidptr) {
|
||||
#a.val.arr.make_copy()
|
||||
#if (arguments[2] && arguments[2].valueOf()) {a.val.arr.arr.push(...val)} else {
|
||||
@ -246,7 +239,7 @@ struct array_iterator {
|
||||
#}
|
||||
#array_iterator.prototype[Symbol.iterator] = function () { return this; }
|
||||
|
||||
#array.prototype[Symbol.iterator] = function () { console.log(this.arr.index_start); return new array_iterator({ix: new int(0),end: new int(this.arr.len),arr: this}); }
|
||||
#array.prototype[Symbol.iterator] = function () { return new array_iterator({ix: new int(0),end: new int(this.arr.len),arr: this}); }
|
||||
#array.prototype.entries = function () { let result = []; for (let key = this.arr.index_start.val;key < this.arr.len.val;key++) { result.push([new int(key), this.arr.get(new int(key))]); } return result[Symbol.iterator](); }
|
||||
#array.prototype.map = function(callback) { return v_map(this,callback); }
|
||||
#array.prototype.filter = function(callback) { return v_filter(this,callback); }
|
||||
|
@ -21,3 +21,19 @@ pub fn (c byte) str() string {
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
pub fn (c byte) ascii_str() string {
|
||||
res := ''
|
||||
#res.str = String.fromCharCode(c.val)
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
pub fn (c byte) repeat(count int) string {
|
||||
mut res := ''
|
||||
for _ in 0 .. count {
|
||||
res += c.ascii_str()
|
||||
}
|
||||
|
||||
return res
|
||||
}
|
||||
|
@ -1,5 +1,26 @@
|
||||
module builtin
|
||||
|
||||
pub fn (i i8) str() string {
|
||||
mut res := ''
|
||||
#res.str = i.val.toString()
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
pub fn (i i16) str() string {
|
||||
mut res := ''
|
||||
#res.str = i.val.toString()
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
pub fn (i u16) str() string {
|
||||
mut res := ''
|
||||
#res.str = i.val.toString()
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
pub fn (i int) str() string {
|
||||
mut res := ''
|
||||
#res = new string( i )
|
||||
@ -48,3 +69,82 @@ pub fn (i int_literal) str() string {
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
pub fn (x u64) hex() string {
|
||||
res := ''
|
||||
#res.str = x.val.toString(16)
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
pub fn (x i64) hex() string {
|
||||
res := ''
|
||||
#res.str = x.val.toString(16)
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
pub fn (x u32) hex() string {
|
||||
res := ''
|
||||
#res.str = x.val.toString(16)
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
pub fn (x u16) hex() string {
|
||||
res := ''
|
||||
#res.str = x.val.toString(16)
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
pub fn (x i8) hex() string {
|
||||
res := ''
|
||||
#res.str = x.val.toString(16)
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
pub fn (x i16) hex() string {
|
||||
res := ''
|
||||
#res.str = x.val.toString(16)
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
pub fn (x int) hex() string {
|
||||
res := ''
|
||||
#res.str = x.val.toString(16)
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
pub fn (x int_literal) hex() string {
|
||||
res := ''
|
||||
#res.str = x.val.toString(16)
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
pub fn (x byte) hex() string {
|
||||
res := ''
|
||||
#res.str = x.val.toString(16)
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
// hex returns a string with the hexadecimal representation
|
||||
// of the byte elements of the array.
|
||||
pub fn (b []byte) hex() string {
|
||||
mut hex := ''
|
||||
for i in b {
|
||||
mut z := i
|
||||
z = z
|
||||
#let n0 = i.val >> 4
|
||||
#hex.str += n0 < 10 ? String.fromCharCode(n0) : String.fromCharCode(n0 + 87)
|
||||
|
||||
#let n1 = i.val & 0xF
|
||||
#hex.str += n1 < 10 ? String.fromCharCode(n1) : String.fromCharCode(n1 + 87)
|
||||
}
|
||||
return hex
|
||||
}
|
||||
|
244
vlib/builtin/js/int_test.js.v
Normal file
244
vlib/builtin/js/int_test.js.v
Normal file
@ -0,0 +1,244 @@
|
||||
const (
|
||||
a = 3
|
||||
u = u64(1)
|
||||
)
|
||||
|
||||
fn test_const() {
|
||||
b := (true && true) || false
|
||||
assert b == true
|
||||
assert a == 3
|
||||
assert u == u64(1)
|
||||
assert u == 1 // make sure this works without the cast
|
||||
}
|
||||
|
||||
fn test_str_methods() {
|
||||
assert i8(1).str() == '1'
|
||||
assert i8(-1).str() == '-1'
|
||||
assert i16(1).str() == '1'
|
||||
assert i16(-1).str() == '-1'
|
||||
assert int(1).str() == '1'
|
||||
assert int(-1).str() == '-1'
|
||||
assert int(2147483647).str() == '2147483647'
|
||||
// todo: overflow check for integers
|
||||
// assert int(2147483648).str() == '-2147483648'
|
||||
// assert int(-2147483648).str() == '-2147483648'
|
||||
assert i64(1).str() == '1'
|
||||
assert i64(-1).str() == '-1'
|
||||
assert u16(1).str() == '1'
|
||||
// assert u16(-1).str() == '65535'
|
||||
assert u32(1).str() == '1'
|
||||
// assert u32(-1).str() == '4294967295'
|
||||
assert u64(1).str() == '1'
|
||||
// assert u64(-1).str() == '18446744073709551615'
|
||||
}
|
||||
|
||||
fn test_and_precendence() {
|
||||
assert (2 & 0 == 0) == ((2 & 0) == 0)
|
||||
assert (2 & 0 != 0) == ((2 & 0) != 0)
|
||||
assert (0 & 0 >= 0) == ((0 & 0) >= 0)
|
||||
assert (0 & 0 <= 0) == ((0 & 0) <= 0)
|
||||
assert (0 & 0 < 1) == ((0 & 0) < 1)
|
||||
assert (1 & 2 > 0) == ((1 & 2) > 0)
|
||||
}
|
||||
|
||||
fn test_or_precendence() {
|
||||
assert (1 | 0 == 0) == ((1 | 0) == 0)
|
||||
assert (1 | 0 != 1) == ((1 | 0) != 1)
|
||||
assert (1 | 0 >= 2) == ((1 | 0) >= 2)
|
||||
assert (1 | 0 <= 0) == ((1 | 0) <= 0)
|
||||
assert (1 | 0 < 0) == ((1 | 0) < 0)
|
||||
assert (1 | 0 > 1) == ((1 | 0) > 1)
|
||||
}
|
||||
|
||||
fn test_xor_precendence() {
|
||||
assert (1 ^ 0 == 2) == ((1 ^ 0) == 2)
|
||||
assert (1 ^ 0 != 2) == ((1 ^ 0) != 2)
|
||||
assert (1 ^ 0 >= 0) == ((1 ^ 0) >= 0)
|
||||
assert (1 ^ 0 <= 1) == ((1 ^ 0) <= 1)
|
||||
assert (1 ^ 0 < 0) == ((1 ^ 0) < 0)
|
||||
assert (1 ^ 0 > 1) == ((1 ^ 0) > 1)
|
||||
}
|
||||
|
||||
fn test_left_shift_precendence() {
|
||||
assert (2 << 4 | 3) == ((2 << 4) | 3)
|
||||
assert (2 << 4 | 3) != (2 << (4 | 3))
|
||||
}
|
||||
|
||||
fn test_right_shift_precendence() {
|
||||
assert (256 >> 4 | 3) == ((256 >> 4) | 3)
|
||||
assert (256 >> 4 | 3) != (256 >> (4 | 3))
|
||||
}
|
||||
|
||||
fn test_i8_print() {
|
||||
b := i8(0)
|
||||
println(b)
|
||||
c := i16(7)
|
||||
println(c)
|
||||
d := u16(6)
|
||||
println(d)
|
||||
assert true
|
||||
}
|
||||
|
||||
/*
|
||||
fn test_cmp() {
|
||||
assert 1 ≠ 2
|
||||
assert 1 ⩽ 2
|
||||
assert 1 ⩾ 0
|
||||
}
|
||||
*/
|
||||
type MyInt = int
|
||||
|
||||
fn test_int_alias() {
|
||||
i := MyInt(2)
|
||||
assert i + 10 == 12
|
||||
}
|
||||
|
||||
fn test_hex() {
|
||||
x := u64(10)
|
||||
assert x.hex() == 'a'
|
||||
b := 1234
|
||||
assert b.hex() == '4d2'
|
||||
b1 := -1
|
||||
// assert b1.hex() == 'ffffffff'
|
||||
// unsigned tests
|
||||
// assert u8(12).hex() == '0c'
|
||||
// assert u8(255).hex() == 'ff'
|
||||
assert u16(65535).hex() == 'ffff'
|
||||
// assert u32(-1).hex() == 'ffffffff'
|
||||
// assert u64(-1).hex() == 'ffffffffffffffff'
|
||||
// signed tests
|
||||
// assert i8(-1).hex() == 'ff'
|
||||
assert i8(12).hex() == 'c'
|
||||
assert i16(32767).hex() == '7fff'
|
||||
assert int(2147483647).hex() == '7fffffff'
|
||||
assert i64(9223372036854775807).hex() == '7fffffffffffffff'
|
||||
}
|
||||
|
||||
fn test_bin() {
|
||||
x1 := 0b10
|
||||
assert x1 == 2
|
||||
x2 := 0b10101010
|
||||
assert x2 == 0xAA
|
||||
x3 := -0b0000001
|
||||
assert x3 == -1
|
||||
x4 := 0b11111111
|
||||
assert x4 == 255
|
||||
x5 := byte(0b11111111)
|
||||
assert x5 == 255
|
||||
x6 := char(0b11111111)
|
||||
assert int(x6) == -1
|
||||
x7 := 0b0
|
||||
assert x7 == 0
|
||||
x8 := -0b0
|
||||
assert x8 == 0
|
||||
}
|
||||
|
||||
fn test_oct() {
|
||||
x1 := 0o12
|
||||
assert x1 == 10
|
||||
x2 := 0o350
|
||||
assert x2 == 232
|
||||
x3 := 0o00073
|
||||
assert x3 == 59
|
||||
x4 := 0
|
||||
assert x4 == 0
|
||||
x5 := 195
|
||||
assert x5 == 195
|
||||
x6 := -0o744
|
||||
assert x6 == -484
|
||||
x7 := -0o000042
|
||||
assert x7 == -34
|
||||
x8 := -112
|
||||
assert x8 == -112
|
||||
x9 := -0
|
||||
assert x9 == 0
|
||||
}
|
||||
|
||||
fn test_num_separator() {
|
||||
// int
|
||||
assert 100_000_0 == 1000000
|
||||
assert -2_23_4_6 == -22346
|
||||
|
||||
// bin
|
||||
assert 0b0_11 == 3
|
||||
assert -0b0_100 == -4
|
||||
|
||||
// oct
|
||||
assert 0o1_73 == 123
|
||||
assert -0o17_5 == -125
|
||||
assert -0o175 == -125
|
||||
|
||||
// hex
|
||||
assert 0xFF == 255
|
||||
assert 0xF_F == 255
|
||||
|
||||
// f32 or f64
|
||||
assert 312_2.55 == 3122.55
|
||||
assert 312_2.55 == 3122.55
|
||||
}
|
||||
|
||||
fn test_int_decl() {
|
||||
x1 := 0
|
||||
x2 := 1333
|
||||
x3 := -88955
|
||||
x4 := 2000000000
|
||||
x5 := -1999999999
|
||||
assert typeof(x1).name == 'int'
|
||||
assert typeof(x2).name == 'int'
|
||||
assert typeof(x3).name == 'int'
|
||||
assert typeof(x4).name == 'int'
|
||||
assert typeof(x5).name == 'int'
|
||||
x7 := u64(-321314588900011)
|
||||
assert typeof(x7).name == 'u64'
|
||||
}
|
||||
|
||||
fn test_int_to_hex() {
|
||||
// array hex
|
||||
/*
|
||||
st := [byte(`V`), `L`, `A`, `N`, `G`]
|
||||
assert st.hex() == '564c414e47'
|
||||
assert st.hex().len == 10
|
||||
st1 := [byte(0x41)].repeat(100)
|
||||
assert st1.hex() == '41'.repeat(100)*/
|
||||
// --- int to hex tests
|
||||
c0 := 12
|
||||
// 8Bit
|
||||
assert byte(0).hex() == '0'
|
||||
assert byte(c0).hex() == 'c'
|
||||
assert i8(c0).hex() == 'c'
|
||||
assert byte(127).hex() == '7f'
|
||||
assert i8(127).hex() == '7f'
|
||||
assert byte(255).hex() == 'ff'
|
||||
// assert byte(-1).hex() == 'ff'
|
||||
// 16bit
|
||||
assert u16(0).hex() == '0'
|
||||
assert i16(c0).hex() == 'c'
|
||||
assert u16(c0).hex() == 'c'
|
||||
assert i16(32767).hex() == '7fff'
|
||||
assert u16(32767).hex() == '7fff'
|
||||
// assert i16(-1).hex() == 'ffff'
|
||||
assert u16(65535).hex() == 'ffff'
|
||||
// 32bit
|
||||
assert u32(0).hex() == '0'
|
||||
assert c0.hex() == 'c'
|
||||
assert u32(c0).hex() == 'c'
|
||||
assert 2147483647.hex() == '7fffffff'
|
||||
assert u32(2147483647).hex() == '7fffffff'
|
||||
// assert (-1).hex() == 'ffffffffffffffff'
|
||||
assert u32(4294967295).hex() == 'ffffffff'
|
||||
// 64 bit
|
||||
assert u64(0).hex() == '0'
|
||||
assert i64(c0).hex() == 'c'
|
||||
assert u64(c0).hex() == 'c'
|
||||
assert i64(9223372036854775807).hex() == '7fffffffffffffff'
|
||||
assert u64(9223372036854775807).hex() == '7fffffffffffffff'
|
||||
// assert i64(-1).hex() == 'ffffffffffffffff'
|
||||
assert u64(18446744073709551615).hex() == 'ffffffffffffffff'
|
||||
}
|
||||
|
||||
fn test_repeat() {
|
||||
b := byte(`V`)
|
||||
assert b.repeat(5) == 'VVVVV'
|
||||
assert b.repeat(1) == b.ascii_str()
|
||||
assert b.repeat(0) == ''
|
||||
}
|
@ -25,3 +25,5 @@ pub fn (m &map) free() {}
|
||||
#res += '}'
|
||||
#return res;
|
||||
#}
|
||||
|
||||
#map.prototype.getOrSet = function (key, init) { if (this.map.has(key)) { return this.map.get(key); } else { this.map.set(key,init); return init; } }
|
||||
|
949
vlib/builtin/js/map_test.js.v
Normal file
949
vlib/builtin/js/map_test.js.v
Normal file
@ -0,0 +1,949 @@
|
||||
import rand
|
||||
|
||||
const (
|
||||
strings = unique_strings(200, 10)
|
||||
)
|
||||
|
||||
fn unique_strings(arr_len int, str_len int) []string {
|
||||
mut arr := []string{cap: arr_len}
|
||||
for arr.len < arr_len {
|
||||
str := rand.string(str_len)
|
||||
if str !in arr {
|
||||
arr << str
|
||||
}
|
||||
}
|
||||
return arr
|
||||
}
|
||||
|
||||
fn test_get_and_set_many() {
|
||||
mut m := map[string]int{}
|
||||
for i, s in strings {
|
||||
m[s] = i
|
||||
assert m[s] == i
|
||||
assert m.len == i + 1
|
||||
}
|
||||
for i, s in strings {
|
||||
assert m[s] == i
|
||||
}
|
||||
assert m.len == strings.len
|
||||
}
|
||||
|
||||
fn test_for_in_many() {
|
||||
mut m := map[string]int{}
|
||||
for i, s in strings {
|
||||
m[s] = i
|
||||
}
|
||||
for k, v in m {
|
||||
assert m[k] == v
|
||||
}
|
||||
}
|
||||
|
||||
fn test_keys_many() {
|
||||
mut m := map[string]int{}
|
||||
for i, s in strings {
|
||||
m[s] = i
|
||||
}
|
||||
keys := m.keys()
|
||||
assert keys.len == strings.len
|
||||
assert keys.len == m.len
|
||||
assert keys == strings
|
||||
}
|
||||
|
||||
fn test_deletes_many() {
|
||||
mut m := map[string]int{}
|
||||
for i, s in strings {
|
||||
m[s] = i
|
||||
}
|
||||
for i, s in strings {
|
||||
m.delete(s)
|
||||
assert m[s] == 0
|
||||
assert m.len == strings.len - (i + 1)
|
||||
}
|
||||
assert m.len == 0
|
||||
assert m.keys().len == 0
|
||||
}
|
||||
|
||||
struct User {
|
||||
mut:
|
||||
name string
|
||||
}
|
||||
|
||||
struct Aaa {
|
||||
mut:
|
||||
m map[string]int
|
||||
users map[string]User
|
||||
}
|
||||
|
||||
fn (mut a Aaa) set(key string, val int) {
|
||||
a.m[key] = val
|
||||
}
|
||||
|
||||
fn test_map() {
|
||||
mut m := map[string]int{}
|
||||
assert m.len == 0
|
||||
m['hi'] = 80
|
||||
m['hello'] = 101
|
||||
assert m['hi'] == 80
|
||||
assert m['hello'] == 101
|
||||
assert m.len == 2
|
||||
assert 'hi' in m
|
||||
mut sum := 0
|
||||
// Test `for in`
|
||||
for _, val in m {
|
||||
sum += val
|
||||
}
|
||||
assert sum == 80 + 101
|
||||
// Test `.keys()`
|
||||
keys := m.keys()
|
||||
assert keys.len == 2
|
||||
assert 'hi' in keys
|
||||
assert 'hello' in keys
|
||||
m.delete('hi')
|
||||
assert m.len == 1
|
||||
m.delete('aloha')
|
||||
assert m.len == 1
|
||||
assert m['hi'] == 0
|
||||
assert m.keys().len == 1
|
||||
assert m.keys()[0] == 'hello'
|
||||
// //
|
||||
mut users := map[string]User{}
|
||||
users['1'] = User{'Peter'}
|
||||
peter := users['1']
|
||||
assert peter.name == 'Peter'
|
||||
mut a := Aaa{
|
||||
m: map[string]int{}
|
||||
users: map[string]User{}
|
||||
}
|
||||
a.users['Bob'] = User{'Bob'}
|
||||
q := a.users['Bob']
|
||||
assert q.name == 'Bob'
|
||||
// test struct field change
|
||||
a.users['Bob'].name = 'bob'
|
||||
q2 := a.users['Bob']
|
||||
assert q2.name == 'bob'
|
||||
a.m['one'] = 1
|
||||
a.set('two', 2)
|
||||
assert a.m['one'] == 1
|
||||
assert a.m['two'] == 2
|
||||
}
|
||||
|
||||
fn test_map_init() {
|
||||
one := 'one'
|
||||
three := 'three'
|
||||
m := {
|
||||
one: 1
|
||||
'two': 2
|
||||
three: 1 + 2
|
||||
}
|
||||
assert m['one'] == 1
|
||||
assert m['two'] == 2
|
||||
assert m['three'] == 3
|
||||
assert m['unknown'] == 0
|
||||
}
|
||||
|
||||
fn test_string_map() {
|
||||
// m := map[string]Fn
|
||||
}
|
||||
|
||||
fn test_large_map() {
|
||||
// ticks := time.ticks()
|
||||
mut nums := map[string]int{}
|
||||
n := 30 * 1000
|
||||
for i in 0 .. n {
|
||||
key := i.str()
|
||||
nums[key] = i
|
||||
}
|
||||
assert nums['1'] == 1
|
||||
assert nums['999'] == 999
|
||||
assert nums['1000000'] == 0
|
||||
// println(time.ticks() - ticks)
|
||||
}
|
||||
|
||||
fn test_various_map_value() {
|
||||
mut m1 := map[string]int{}
|
||||
m1['test'] = 1
|
||||
assert m1['test'] == 1
|
||||
mut m2 := map[string]string{}
|
||||
m2['test'] = 'test'
|
||||
assert m2['test'] == 'test'
|
||||
mut m3 := map[string]i8{}
|
||||
m3['test'] = i8(0)
|
||||
assert m3['test'] == i8(0)
|
||||
mut m4 := map[string]i16{}
|
||||
m4['test'] = i16(0)
|
||||
assert m4['test'] == i16(0)
|
||||
mut m7 := map[string]u16{}
|
||||
m7['test'] = u16(0)
|
||||
assert m7['test'] == u16(0)
|
||||
mut m8 := map[string]u32{}
|
||||
m8['test'] = u32(0)
|
||||
assert m8['test'] == u32(0)
|
||||
mut m9 := map[string]bool{}
|
||||
m9['test'] = true
|
||||
assert m9['test'] == true
|
||||
mut m10 := map[string]byte{}
|
||||
m10['test'] = byte(0)
|
||||
assert m10['test'] == byte(0)
|
||||
mut m11 := map[string]f32{}
|
||||
m11['test'] = f32(0.0)
|
||||
assert m11['test'] == f32(0.0)
|
||||
mut m12 := map[string]f64{}
|
||||
m12['test'] = f64(0.0)
|
||||
assert m12['test'] == f64(0.0)
|
||||
// mut m13 := map[string]rune
|
||||
// m13['test'] = rune(0)
|
||||
// assert m13['test'] == rune(0)
|
||||
// todo(playX): pointer equality does not work yet
|
||||
/*
|
||||
mut m14 := map[string]voidptr{}
|
||||
m14['test'] = voidptr(0)
|
||||
assert m14['test'] == voidptr(0)
|
||||
mut m15 := map[string]&byte{}
|
||||
m15['test'] = &byte(0)
|
||||
assert m15['test'] == &byte(0)
|
||||
mut m16 := map[string]i64{}
|
||||
m16['test'] = i64(0)
|
||||
assert m16['test'] == i64(0)
|
||||
mut m17 := map[string]u64{}
|
||||
m17['test'] = u64(0)
|
||||
assert m17['test'] == u64(0)
|
||||
mut m18 := map[string]&int{}
|
||||
m18['test'] = &int(0)
|
||||
assert m18['test'] == &int(0)*/
|
||||
}
|
||||
|
||||
fn test_string_arr() {
|
||||
mut m := map[string][]string{}
|
||||
m['a'] = ['one', 'two']
|
||||
assert m['a'].len == 2
|
||||
assert m['a'][0] == 'one'
|
||||
assert m['a'][1] == 'two'
|
||||
}
|
||||
|
||||
fn mut_map(mut m map[string]int) {
|
||||
m['a'] = 10
|
||||
}
|
||||
|
||||
fn test_mut_arg() {
|
||||
mut m := map[string]int{}
|
||||
mut_map(mut m)
|
||||
a := m['a']
|
||||
assert a == 10
|
||||
}
|
||||
|
||||
fn test_delete() {
|
||||
mut m := map[string]int{}
|
||||
m['one'] = 1
|
||||
m['two'] = 2
|
||||
println(m['two']) // => "2"
|
||||
m.delete('two')
|
||||
println(m['two'].str()) // => 0
|
||||
assert ('two' in m) == false
|
||||
println('two' in m) // => true, on Linux and Windows <-- wrong !
|
||||
}
|
||||
|
||||
fn test_delete_size() {
|
||||
arr := ['0', '1', '2', '3', '4', '5', '6', '7', '8', '9']
|
||||
mut m := map[string]int{}
|
||||
for _ in 0 .. 10 {
|
||||
for i in 0 .. 10 {
|
||||
m[arr[i]] = i
|
||||
}
|
||||
assert m.len == 10
|
||||
println(m.len)
|
||||
for i in 0 .. 10 {
|
||||
m.delete(arr[i])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn test_nested_for_in() {
|
||||
mut m := map[string]int{}
|
||||
for i in 0 .. 1000 {
|
||||
m[i.str()] = i
|
||||
}
|
||||
mut i := 0
|
||||
for key1, _ in m {
|
||||
assert key1 == i.str()
|
||||
i++
|
||||
mut j := 0
|
||||
for key2, _ in m {
|
||||
assert key2 == j.str()
|
||||
j++
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn test_delete_in_for_in() {
|
||||
mut m := map[string]string{}
|
||||
for i in 0 .. 1000 {
|
||||
m[i.str()] = i.str()
|
||||
}
|
||||
mut i := 0
|
||||
for key, _ in m {
|
||||
assert key == i.str()
|
||||
m.delete(key)
|
||||
i++
|
||||
}
|
||||
assert m.str() == '{}'
|
||||
assert m.len == 0
|
||||
}
|
||||
|
||||
fn test_set_in_for_in() {
|
||||
mut m := map[string]string{}
|
||||
for i in 0 .. 10 {
|
||||
m[i.str()] = i.str()
|
||||
}
|
||||
mut last_key := ''
|
||||
mut i := 0
|
||||
for key, _ in m {
|
||||
m['10'] = '10'
|
||||
assert key == i.str()
|
||||
last_key = key
|
||||
i++
|
||||
}
|
||||
assert last_key == '10'
|
||||
}
|
||||
|
||||
fn test_delete_and_set_in_for_in() {
|
||||
mut m := map[string]string{}
|
||||
for i in 0 .. 1000 {
|
||||
m[i.str()] = i.str()
|
||||
}
|
||||
mut i := 0
|
||||
for key, _ in m {
|
||||
assert key == i.str()
|
||||
m.delete(key)
|
||||
m[key] = i.str()
|
||||
if i == 999 {
|
||||
break
|
||||
}
|
||||
i++
|
||||
}
|
||||
assert m.len == 1000
|
||||
i = 0
|
||||
for key, _ in m {
|
||||
assert m[key] == i.str()
|
||||
i++
|
||||
}
|
||||
assert i == 1000
|
||||
}
|
||||
|
||||
struct Mstruct1 {
|
||||
pub mut:
|
||||
mymap map[string]int
|
||||
}
|
||||
|
||||
struct Mstruct2 {
|
||||
pub mut:
|
||||
mymap map[string]f64
|
||||
}
|
||||
|
||||
struct Mstruct3 {
|
||||
pub mut:
|
||||
mymap map[string]u16
|
||||
}
|
||||
|
||||
fn test_map_assign() {
|
||||
mut a := map[string]f64{}
|
||||
mut b := map[string]int{}
|
||||
mut c := map[string]u16{}
|
||||
a = {
|
||||
'x': 12.4
|
||||
'y': 3
|
||||
}
|
||||
b = {
|
||||
'u': -13
|
||||
'v': 12
|
||||
}
|
||||
c = {
|
||||
's': u16(5)
|
||||
't': 3
|
||||
}
|
||||
_ := Mstruct1{{
|
||||
'p': 12
|
||||
}}
|
||||
_ := Mstruct2{{
|
||||
'q': 1.7
|
||||
}}
|
||||
_ := Mstruct3{{
|
||||
'r': u16(6)
|
||||
's': 5
|
||||
}}
|
||||
}
|
||||
|
||||
fn test_postfix_op_directly() {
|
||||
mut a := map[string]int{}
|
||||
a['aaa']++
|
||||
assert a['aaa'] == 1
|
||||
a['aaa']++
|
||||
assert a['aaa'] == 2
|
||||
a['bbb']--
|
||||
assert a['bbb'] == -1
|
||||
a['bbb']--
|
||||
assert a['bbb'] == -2
|
||||
}
|
||||
|
||||
fn test_map_push_directly() {
|
||||
mut a := map[string][]string{}
|
||||
a['aaa'] << ['a', 'b', 'c']
|
||||
assert a['aaa'].len == 3
|
||||
assert a['aaa'] == ['a', 'b', 'c']
|
||||
}
|
||||
|
||||
fn test_assign_directly() {
|
||||
mut a := map[string]int{}
|
||||
a['aaa'] += 4
|
||||
assert a['aaa'] == 4
|
||||
a['aaa'] -= 2
|
||||
assert a['aaa'] == 2
|
||||
}
|
||||
|
||||
fn test_map_in_directly() {
|
||||
for k, v in {
|
||||
'aa': 1
|
||||
} {
|
||||
assert k == 'aa'
|
||||
assert v == 1
|
||||
}
|
||||
}
|
||||
|
||||
fn test_plus_assign_string() {
|
||||
mut m := {
|
||||
'one': ''
|
||||
}
|
||||
m['one'] += '1'
|
||||
assert m.len == 1
|
||||
assert m['one'] == '1'
|
||||
}
|
||||
|
||||
fn test_map_keys_to_array() {
|
||||
m := {
|
||||
'a': 'b'
|
||||
'c': 'd'
|
||||
}
|
||||
mut arr := []string{}
|
||||
for k, _ in m {
|
||||
arr << k
|
||||
}
|
||||
sarr := arr.str()
|
||||
println(sarr)
|
||||
assert sarr == "['a', 'c']"
|
||||
}
|
||||
|
||||
fn map_in_mut(mut m map[string]int) {
|
||||
if 'one' in m {
|
||||
m['one'] = 2
|
||||
}
|
||||
}
|
||||
|
||||
fn test_map_in_mut() {
|
||||
mut m := {
|
||||
'one': 1
|
||||
}
|
||||
map_in_mut(mut m)
|
||||
assert m['one'] == 2
|
||||
}
|
||||
|
||||
fn test_map_in() {
|
||||
m := {
|
||||
'Foo': 'bar'
|
||||
}
|
||||
if 'foo'.capitalize() in m {
|
||||
println('ok')
|
||||
} else {
|
||||
assert false
|
||||
}
|
||||
}
|
||||
|
||||
fn mut_map_with_relation_op_in_fn(mut m map[string]int) {
|
||||
if m['one'] == 1 {
|
||||
m['three'] = 3
|
||||
}
|
||||
if m['two'] != 1 {
|
||||
m['four'] = 4
|
||||
}
|
||||
if m['one'] > 0 {
|
||||
m['five'] = 5
|
||||
}
|
||||
if m['one'] < 2 {
|
||||
m['six'] = 6
|
||||
}
|
||||
if m['two'] >= 2 {
|
||||
m['seven'] = 7
|
||||
}
|
||||
if m['two'] <= 2 {
|
||||
m['eight'] = 8
|
||||
}
|
||||
}
|
||||
|
||||
fn test_mut_map_with_relation_op_in_fn() {
|
||||
mut m := {
|
||||
'one': 1
|
||||
'two': 2
|
||||
}
|
||||
mut_map_with_relation_op_in_fn(mut m)
|
||||
assert 'three' in m
|
||||
assert 'four' in m
|
||||
assert 'five' in m
|
||||
assert 'six' in m
|
||||
assert 'seven' in m
|
||||
assert 'eight' in m
|
||||
}
|
||||
|
||||
fn test_map_str_after_delete() {
|
||||
mut m := {
|
||||
'first': 1
|
||||
'second': 2
|
||||
'third': 3
|
||||
}
|
||||
osm := '$m'
|
||||
m.delete('second')
|
||||
nsm := '$m'
|
||||
println('m: $m')
|
||||
assert osm == "{'first': 1, 'second': 2, 'third': 3}"
|
||||
assert nsm == "{'first': 1, 'third': 3}"
|
||||
}
|
||||
|
||||
fn test_modify_map_value() {
|
||||
mut m1 := {
|
||||
'foo': 3
|
||||
'bar': -7
|
||||
}
|
||||
m1['foo'] += 5
|
||||
m1['bar'] *= -2
|
||||
assert m1['foo'] == 8
|
||||
assert m1['bar'] == 14
|
||||
}
|
||||
|
||||
fn test_map_clone() {
|
||||
mut nums := {
|
||||
'foo': 1
|
||||
'bar': 2
|
||||
}
|
||||
mut nums2 := nums.clone()
|
||||
nums2['foo']++
|
||||
nums2['bar'] *= 4
|
||||
assert nums['foo'] == 1
|
||||
assert nums['bar'] == 2
|
||||
assert nums2['foo'] == 2
|
||||
assert nums2['bar'] == 8
|
||||
}
|
||||
|
||||
struct MValue {
|
||||
name string
|
||||
misc map[string]string
|
||||
}
|
||||
|
||||
fn test_map_default_zero() {
|
||||
m := map[string]MValue{}
|
||||
v := m['unknown']
|
||||
x := v.misc['x']
|
||||
println(x)
|
||||
assert x == ''
|
||||
}
|
||||
|
||||
fn test_map_or() {
|
||||
m := {
|
||||
'first': 1
|
||||
'second': 2
|
||||
'third': 3
|
||||
}
|
||||
_ = m
|
||||
// num := m['first'] or { return }
|
||||
}
|
||||
|
||||
fn test_int_keys() {
|
||||
mut m := map[int]int{}
|
||||
m[3] = 9
|
||||
m[4] = 16
|
||||
assert m.len == 2
|
||||
assert m[3] == 9
|
||||
assert m[4] == 16
|
||||
m[5] += 24
|
||||
m[5]++
|
||||
assert m[5] == 25
|
||||
mut m2 := {
|
||||
3: 9
|
||||
4: 16
|
||||
5: 25
|
||||
}
|
||||
|
||||
four := 4
|
||||
m2.delete(3)
|
||||
m2.delete(four)
|
||||
m2.delete(5)
|
||||
assert m2.len == 0
|
||||
assert m2[3] == 0
|
||||
assert m2[4] == 0
|
||||
assert m2[5] == 0
|
||||
assert m2.keys() == []
|
||||
|
||||
m2 = {
|
||||
3: 9
|
||||
4: 16
|
||||
5: 25
|
||||
}
|
||||
|
||||
assert m2.len == 3
|
||||
// clone
|
||||
mc := m.clone()
|
||||
same := mc == m
|
||||
assert same
|
||||
assert mc.len == 3
|
||||
assert mc.keys() == [3, 4, 5]
|
||||
mut all := []int{}
|
||||
for k, v in mc {
|
||||
assert m[k] == v
|
||||
all << k
|
||||
all << v
|
||||
}
|
||||
assert all == [3, 9, 4, 16, 5, 25]
|
||||
|
||||
mut m3 := {
|
||||
1: 'one'
|
||||
2: 'two'
|
||||
}
|
||||
assert m3[1] == 'one'
|
||||
m3.delete(1)
|
||||
}
|
||||
|
||||
enum Color {
|
||||
red
|
||||
green
|
||||
blue
|
||||
}
|
||||
|
||||
type ColorAlias = Color
|
||||
|
||||
fn test_alias_enum() {
|
||||
mut m := map[ColorAlias]string{}
|
||||
m[Color.red] = 'hi'
|
||||
assert m[Color.red] == 'hi'
|
||||
}
|
||||
|
||||
fn test_enum_in_map() {
|
||||
mut m := map[Color]string{}
|
||||
m[Color.red] = 'hi'
|
||||
assert Color.red in m
|
||||
assert Color.green !in m
|
||||
assert Color.blue !in m
|
||||
}
|
||||
|
||||
fn test_voidptr_keys() {
|
||||
mut m := map[voidptr]string{}
|
||||
v := 5
|
||||
m[&v] = 'var'
|
||||
m[&m] = 'map'
|
||||
assert m[&v] == 'var'
|
||||
assert m[&m] == 'map'
|
||||
assert m.len == 2
|
||||
}
|
||||
|
||||
fn test_rune_keys() {
|
||||
mut m := {
|
||||
`!`: 2
|
||||
`%`: 3
|
||||
}
|
||||
assert typeof(m).name == 'map[rune]int'
|
||||
assert m[`!`] == 2
|
||||
m[`@`] = 7
|
||||
assert m.len == 3
|
||||
println(m)
|
||||
assert '$m' == '{`!`: 2, `%`: 3, `@`: 7}'
|
||||
|
||||
mut a := []rune{}
|
||||
for k, v in m {
|
||||
a << k
|
||||
a << rune(v) + `0`
|
||||
}
|
||||
assert a == [`!`, `2`, `%`, `3`, `@`, `7`]
|
||||
}
|
||||
|
||||
fn test_eq() {
|
||||
a := {
|
||||
'a': 1
|
||||
'b': 2
|
||||
}
|
||||
assert a == {
|
||||
'a': 1
|
||||
'b': 2
|
||||
}
|
||||
b := {
|
||||
'a': [[1]]
|
||||
'b': [[2]]
|
||||
}
|
||||
assert b == {
|
||||
'a': [[1]]
|
||||
'b': [[2]]
|
||||
}
|
||||
c := {
|
||||
'a': {
|
||||
'11': 1
|
||||
}
|
||||
'b': {
|
||||
'22': 2
|
||||
}
|
||||
}
|
||||
assert c == {
|
||||
'a': {
|
||||
'11': 1
|
||||
}
|
||||
'b': {
|
||||
'22': 2
|
||||
}
|
||||
}
|
||||
d := {
|
||||
'a': MValue{
|
||||
name: 'aa'
|
||||
misc: {
|
||||
'11': '1'
|
||||
}
|
||||
}
|
||||
'b': MValue{
|
||||
name: 'bb'
|
||||
misc: {
|
||||
'22': '2'
|
||||
}
|
||||
}
|
||||
}
|
||||
assert d == {
|
||||
'a': MValue{
|
||||
name: 'aa'
|
||||
misc: {
|
||||
'11': '1'
|
||||
}
|
||||
}
|
||||
'b': MValue{
|
||||
name: 'bb'
|
||||
misc: {
|
||||
'22': '2'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn test_non_string_key_map_str() {
|
||||
assert {
|
||||
23: 4
|
||||
}.str() == '{23: 4}'
|
||||
assert {
|
||||
`a`: 12
|
||||
`b`: 13
|
||||
}.str() == '{`a`: 12, `b`: 13}'
|
||||
assert {
|
||||
23: 'foo'
|
||||
25: 'bar'
|
||||
}.str() == "{23: 'foo', 25: 'bar'}"
|
||||
}
|
||||
|
||||
fn test_map_assign_empty_map_init() {
|
||||
mut a := {
|
||||
'one': 1
|
||||
}
|
||||
a = {}
|
||||
println(a)
|
||||
assert a == map[string]int{}
|
||||
assert '$a' == '{}'
|
||||
}
|
||||
|
||||
fn test_in_map_literal() {
|
||||
assert 1 in {
|
||||
1: 'one'
|
||||
}
|
||||
}
|
||||
|
||||
fn test_byte_keys() {
|
||||
mut m := map[byte]byte{}
|
||||
byte_max := byte(255)
|
||||
for i in byte(0) .. byte_max {
|
||||
m[i] = i
|
||||
assert m[i] == i
|
||||
}
|
||||
for k, v in m {
|
||||
assert k == v
|
||||
}
|
||||
for i in byte(0) .. 100 {
|
||||
m[i]++
|
||||
assert m[i] == i + 1
|
||||
}
|
||||
assert m.len == byte_max
|
||||
keys := m.keys()
|
||||
for i in byte(0) .. byte_max {
|
||||
assert keys[i] == i
|
||||
}
|
||||
for i in byte(0) .. byte_max {
|
||||
m.delete(i)
|
||||
assert m[i] == 0
|
||||
}
|
||||
assert m.len == 0
|
||||
}
|
||||
|
||||
fn test_i16_keys() {
|
||||
mut m := map[i16]i16{}
|
||||
end := i16(1000)
|
||||
for i in i16(0) .. end {
|
||||
m[i] = i
|
||||
assert m[i] == i
|
||||
}
|
||||
for k, v in m {
|
||||
assert k == v
|
||||
}
|
||||
for i in i16(0) .. 500 {
|
||||
m[i]++
|
||||
assert m[i] == i + 1
|
||||
}
|
||||
assert m.len == end
|
||||
keys := m.keys()
|
||||
for i in i16(0) .. end {
|
||||
assert keys[i] == i
|
||||
}
|
||||
for i in i16(0) .. end {
|
||||
m.delete(i)
|
||||
assert m[i] == 0
|
||||
}
|
||||
assert m.len == 0
|
||||
}
|
||||
|
||||
fn test_u16_keys() {
|
||||
mut m := map[u16]u16{}
|
||||
end := u16(1000)
|
||||
for i in u16(0) .. end {
|
||||
m[i] = i
|
||||
assert m[i] == i
|
||||
}
|
||||
for k, v in m {
|
||||
assert k == v
|
||||
}
|
||||
for i in u16(0) .. 500 {
|
||||
m[i]++
|
||||
assert m[i] == i + 1
|
||||
}
|
||||
assert m.len == end
|
||||
keys := m.keys()
|
||||
for i in u16(0) .. end {
|
||||
assert keys[i] == i
|
||||
}
|
||||
for i in u16(0) .. end {
|
||||
m.delete(i)
|
||||
assert m[i] == 0
|
||||
}
|
||||
assert m.len == 0
|
||||
}
|
||||
|
||||
fn test_u32_keys() {
|
||||
mut m := map[u32]u32{}
|
||||
end := u32(1000)
|
||||
for i in u32(0) .. end {
|
||||
m[i] = i
|
||||
assert m[i] == i
|
||||
}
|
||||
for k, v in m {
|
||||
assert k == v
|
||||
}
|
||||
for i in u32(0) .. 500 {
|
||||
m[i]++
|
||||
assert m[i] == i + 1
|
||||
}
|
||||
assert m.len == end
|
||||
keys := m.keys()
|
||||
for i in u32(0) .. end {
|
||||
assert keys[i] == i
|
||||
}
|
||||
for i in u32(0) .. end {
|
||||
m.delete(i)
|
||||
assert m[i] == 0
|
||||
}
|
||||
assert m.len == 0
|
||||
}
|
||||
|
||||
fn test_int_keys2() {
|
||||
mut m := map[int]int{}
|
||||
end := 1000
|
||||
for i in int(0) .. end {
|
||||
m[i] = i
|
||||
assert m[i] == i
|
||||
}
|
||||
for k, v in m {
|
||||
assert k == v
|
||||
}
|
||||
for i in int(0) .. 500 {
|
||||
m[i]++
|
||||
assert m[i] == i + 1
|
||||
}
|
||||
assert m.len == end
|
||||
keys := m.keys()
|
||||
for i in int(0) .. end {
|
||||
assert keys[i] == i
|
||||
}
|
||||
for i in int(0) .. end {
|
||||
m.delete(i)
|
||||
assert m[i] == 0
|
||||
}
|
||||
assert m.len == 0
|
||||
}
|
||||
|
||||
fn test_i64_keys() {
|
||||
mut m := map[i64]i64{}
|
||||
end := i64(1000)
|
||||
for i in i64(0) .. end {
|
||||
m[i] = i
|
||||
assert m[i] == i
|
||||
}
|
||||
for k, v in m {
|
||||
assert k == v
|
||||
}
|
||||
for i in i64(0) .. 500 {
|
||||
m[i]++
|
||||
assert m[i] == i + 1
|
||||
}
|
||||
assert m.len == end
|
||||
keys := m.keys()
|
||||
for i in i64(0) .. end {
|
||||
assert keys[i] == i
|
||||
}
|
||||
for i in i64(0) .. end {
|
||||
m.delete(i)
|
||||
assert m[i] == 0
|
||||
}
|
||||
assert m.len == 0
|
||||
}
|
||||
|
||||
fn test_u64_keys() {
|
||||
mut m := map[u64]u64{}
|
||||
end := u64(1000)
|
||||
for i in u64(0) .. end {
|
||||
m[i] = i
|
||||
assert m[i] == i
|
||||
}
|
||||
for k, v in m {
|
||||
assert k == v
|
||||
}
|
||||
for i in u64(0) .. 500 {
|
||||
m[i]++
|
||||
assert m[i] == i + 1
|
||||
}
|
||||
assert m.len == end
|
||||
keys := m.keys()
|
||||
for i in u64(0) .. end {
|
||||
assert keys[i] == i
|
||||
}
|
||||
for i in u64(0) .. end {
|
||||
m.delete(i)
|
||||
assert m[i] == 0
|
||||
}
|
||||
assert m.len == 0
|
||||
}
|
||||
|
||||
fn test_map_set_fixed_array_variable() {
|
||||
mut m := map[string][2]f64{}
|
||||
m['A'] = [1.1, 2.2]!
|
||||
println(m)
|
||||
assert '$m' == "{'A': [1.1, 2.2]}"
|
||||
|
||||
mut m2 := map[string][2]f64{}
|
||||
arr := [1.1, 2.2]!
|
||||
m2['A'] = arr
|
||||
println(m2)
|
||||
assert '$m2' == "{'A': [1.1, 2.2]}"
|
||||
}
|
@ -10,6 +10,10 @@ pub fn (s string) slice(a int, b int) string {
|
||||
return string(s.str.slice(a, b))
|
||||
}
|
||||
|
||||
pub fn (s string) substr(start int, end int) string {
|
||||
return s.slice(start, end)
|
||||
}
|
||||
|
||||
pub fn (s string) after(dot string) string {
|
||||
return string(s.str.slice(s.str.lastIndexOf(dot.str) + 1, int(s.str.length)))
|
||||
}
|
||||
@ -20,20 +24,37 @@ pub fn (s string) after_char(dot byte) string {
|
||||
}
|
||||
|
||||
pub fn (s string) all_after(dot string) string {
|
||||
return string(s.str.slice(s.str.indexOf(dot.str) + 1, int(s.str.length)))
|
||||
pos := if dot.len == 0 { -1 } else { s.str.indexOf(dot.str) }
|
||||
if pos == -1 {
|
||||
return s.clone()
|
||||
}
|
||||
return s[pos + dot.len..]
|
||||
}
|
||||
|
||||
// why does this exist?
|
||||
pub fn (s string) all_after_last(dot string) string {
|
||||
return s.after(dot)
|
||||
pos := if dot.len == 0 { -1 } else { s.str.lastIndexOf(dot.str) }
|
||||
if pos == -1 {
|
||||
return s.clone()
|
||||
}
|
||||
return s[pos + dot.len..]
|
||||
}
|
||||
|
||||
pub fn (s string) all_before(dot string) string {
|
||||
return string(s.str.slice(0, s.str.indexOf(dot.str)))
|
||||
pos := if dot.len == 0 { -1 } else { s.str.indexOf(dot.str) }
|
||||
if pos == -1 {
|
||||
return s.clone()
|
||||
}
|
||||
return s[..pos]
|
||||
// return string(s.str.slice(0, s.str.indexOf(dot.str)))
|
||||
}
|
||||
|
||||
pub fn (s string) all_before_last(dot string) string {
|
||||
return string(s.str.slice(0, s.str.lastIndexOf(dot.str)))
|
||||
pos := if dot.len == 0 { -1 } else { s.str.lastIndexOf(dot.str) }
|
||||
if pos == -1 {
|
||||
return s.clone()
|
||||
}
|
||||
return s[..pos]
|
||||
}
|
||||
|
||||
pub fn (s string) bool() bool {
|
||||
@ -79,6 +100,9 @@ pub fn (s string) contains_any(chars string) bool {
|
||||
}
|
||||
|
||||
pub fn (s string) contains_any_substr(chars []string) bool {
|
||||
if chars.len == 0 {
|
||||
return true
|
||||
}
|
||||
for x in chars {
|
||||
if s.str.includes(x.str) {
|
||||
return true
|
||||
@ -726,3 +750,131 @@ pub fn (s string) replace_once(rep string, with_ string) string {
|
||||
|
||||
return s2
|
||||
}
|
||||
|
||||
pub fn (s string) title() string {
|
||||
words := s.split(' ')
|
||||
mut tit := []string{}
|
||||
for word in words {
|
||||
tit << word.capitalize()
|
||||
}
|
||||
|
||||
title := tit.join(' ')
|
||||
return title
|
||||
}
|
||||
|
||||
// index_any returns the position of any of the characters in the input string - if found.
|
||||
pub fn (s string) index_any(chars string) int {
|
||||
for i, ss in s {
|
||||
for c in chars {
|
||||
if c == ss {
|
||||
return i
|
||||
}
|
||||
}
|
||||
}
|
||||
return -1
|
||||
}
|
||||
|
||||
/*
|
||||
// limit returns a portion of the string, starting at `0` and extending for a given number of characters afterward.
|
||||
// 'hello'.limit(2) => 'he'
|
||||
// 'hi'.limit(10) => 'hi'
|
||||
pub fn (s string) limit(max int) string {
|
||||
u := s.runes()
|
||||
if u.len <= max {
|
||||
return s.clone()
|
||||
}
|
||||
return u[0..max].string()
|
||||
}
|
||||
*/
|
||||
// is_title returns true if all words of the string is capitalized.
|
||||
// Example: assert 'Hello V Developer'.is_title() == true
|
||||
pub fn (s string) is_title() bool {
|
||||
words := s.split(' ')
|
||||
for word in words {
|
||||
if !word.is_capital() {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// is_capital returns `true` if the first character in the string is a capital letter.
|
||||
// Example: assert 'Hello'.is_capital() == true
|
||||
[direct_array_access]
|
||||
pub fn (s string) is_capital() bool {
|
||||
if s.len == 0 || !(s[0] >= `A` && s[0] <= `Z`) {
|
||||
return false
|
||||
}
|
||||
for i in 1 .. s.len {
|
||||
if s[i] >= `A` && s[i] <= `Z` {
|
||||
return false
|
||||
}
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
// is_upper returns `true` if all characters in the string is uppercase.
|
||||
// Example: assert 'HELLO V'.is_upper() == true
|
||||
pub fn (s string) is_upper() bool {
|
||||
res := false
|
||||
#res.val = s.str == s.str.toUpperCase() && s.str != s.str.toLowerCase()
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
// is_upper returns `true` if all characters in the string is uppercase.
|
||||
// Example: assert 'HELLO V'.is_upper() == true
|
||||
pub fn (s string) is_lower() bool {
|
||||
res := false
|
||||
#res.val = s.str == s.str.toLowerCase() && s.str != s.str.toUpperCase()
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
pub fn (s string) reverse() string {
|
||||
res := ''
|
||||
#res.str = [...s.str].reverse().join('')
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
pub fn (s string) trim(cutset string) string {
|
||||
if s.len < 1 || cutset.len < 1 {
|
||||
return s.clone()
|
||||
}
|
||||
mut pos_left := 0
|
||||
mut pos_right := s.len - 1
|
||||
mut cs_match := true
|
||||
for pos_left <= s.len && pos_right >= -1 && cs_match {
|
||||
cs_match = false
|
||||
for cs in cutset {
|
||||
if s[pos_left] == cs {
|
||||
pos_left++
|
||||
cs_match = true
|
||||
break
|
||||
}
|
||||
}
|
||||
for cs in cutset {
|
||||
if s[pos_right] == cs {
|
||||
pos_right--
|
||||
cs_match = true
|
||||
break
|
||||
}
|
||||
}
|
||||
if pos_left > pos_right {
|
||||
return ''
|
||||
}
|
||||
}
|
||||
return s.substr(pos_left, pos_right + 1)
|
||||
}
|
||||
|
||||
pub fn (s []string) join(sep string) string {
|
||||
mut res := ''
|
||||
for i, str in s {
|
||||
res += str
|
||||
if i != s.len - 1 {
|
||||
res += sep
|
||||
}
|
||||
}
|
||||
return res
|
||||
}
|
||||
|
897
vlib/builtin/js/string_test.js.v
Normal file
897
vlib/builtin/js/string_test.js.v
Normal file
@ -0,0 +1,897 @@
|
||||
import strings
|
||||
|
||||
// Copyright (c) 2019-2021 Alexander Medvednikov. All rights reserved.
|
||||
// Use of this source code is governed by an MIT license
|
||||
// that can be found in the LICENSE file.
|
||||
|
||||
struct Foo {
|
||||
bar int
|
||||
mut:
|
||||
str string
|
||||
}
|
||||
|
||||
fn test_add() {
|
||||
mut a := 'a'
|
||||
a += 'b'
|
||||
assert a == ('ab')
|
||||
a = 'a'
|
||||
for i := 1; i < 1000; i++ {
|
||||
a += 'b'
|
||||
}
|
||||
assert a.len == 1000
|
||||
assert a.ends_with('bbbbb')
|
||||
a += '123'
|
||||
assert a.ends_with('3')
|
||||
}
|
||||
|
||||
fn test_ends_with() {
|
||||
a := 'browser.v'
|
||||
assert a.ends_with('.v')
|
||||
|
||||
s := 'V Programming Language'
|
||||
assert s.ends_with('guage') == true
|
||||
assert s.ends_with('Language') == true
|
||||
assert s.ends_with('Programming Language') == true
|
||||
assert s.ends_with('V') == false
|
||||
}
|
||||
|
||||
fn test_between() {
|
||||
s := 'hello [man] how you doing'
|
||||
assert s.find_between('[', ']') == 'man'
|
||||
}
|
||||
|
||||
fn test_compare() {
|
||||
a := 'Music'
|
||||
b := 'src'
|
||||
assert b >= a
|
||||
}
|
||||
|
||||
fn test_lt() {
|
||||
a := ''
|
||||
b := 'a'
|
||||
c := 'a'
|
||||
d := 'b'
|
||||
e := 'aa'
|
||||
f := 'ab'
|
||||
assert a < b
|
||||
assert !(b < c)
|
||||
assert c < d
|
||||
assert !(d < e)
|
||||
assert c < e
|
||||
assert e < f
|
||||
}
|
||||
|
||||
fn test_ge() {
|
||||
a := 'aa'
|
||||
b := 'aa'
|
||||
c := 'ab'
|
||||
d := 'abc'
|
||||
e := 'aaa'
|
||||
assert b >= a
|
||||
assert c >= b
|
||||
assert d >= c
|
||||
assert !(c >= d)
|
||||
assert e >= a
|
||||
}
|
||||
|
||||
fn test_compare_strings() {
|
||||
a := 'aa'
|
||||
b := 'aa'
|
||||
c := 'ab'
|
||||
d := 'abc'
|
||||
e := 'aaa'
|
||||
assert compare_strings(a, b) == 0
|
||||
assert compare_strings(b, c) == -1
|
||||
assert compare_strings(c, d) == -1
|
||||
assert compare_strings(d, e) == 1
|
||||
assert compare_strings(a, e) == -1
|
||||
assert compare_strings(e, a) == 1
|
||||
}
|
||||
|
||||
fn test_sort() {
|
||||
mut vals := [
|
||||
'arr',
|
||||
'an',
|
||||
'a',
|
||||
'any',
|
||||
]
|
||||
len := vals.len
|
||||
vals.sort()
|
||||
assert len == vals.len
|
||||
assert vals[0] == 'a'
|
||||
assert vals[1] == 'an'
|
||||
assert vals[2] == 'any'
|
||||
assert vals[3] == 'arr'
|
||||
}
|
||||
|
||||
fn test_sort_reverse() {
|
||||
mut vals := [
|
||||
'arr',
|
||||
'an',
|
||||
'a',
|
||||
'any',
|
||||
]
|
||||
len := vals.len
|
||||
vals.sort(b > a)
|
||||
assert len == vals.len
|
||||
assert vals[0] == 'a'
|
||||
assert vals[1] == 'an'
|
||||
assert vals[2] == 'any'
|
||||
assert vals[3] == 'arr'
|
||||
}
|
||||
|
||||
fn test_split_nth() {
|
||||
a := '1,2,3'
|
||||
assert a.split(',').len == 3
|
||||
assert a.split_nth(',', -1).len == 3
|
||||
assert a.split_nth(',', 0).len == 3
|
||||
assert a.split_nth(',', 1).len == 1
|
||||
assert a.split_nth(',', 2).len == 2
|
||||
assert a.split_nth(',', 10).len == 3
|
||||
b := '1::2::3'
|
||||
assert b.split('::').len == 3
|
||||
assert b.split_nth('::', -1).len == 3
|
||||
assert b.split_nth('::', 0).len == 3
|
||||
assert b.split_nth('::', 1).len == 1
|
||||
assert b.split_nth('::', 2).len == 2
|
||||
assert b.split_nth('::', 10).len == 3
|
||||
c := 'ABCDEF'
|
||||
println(c.split('').len)
|
||||
assert c.split('').len == 6
|
||||
assert c.split_nth('', 3).len == 3
|
||||
assert c.split_nth('BC', -1).len == 2
|
||||
d := ','
|
||||
assert d.split(',').len == 2
|
||||
assert d.split_nth('', 3).len == 1
|
||||
assert d.split_nth(',', -1).len == 2
|
||||
assert d.split_nth(',', 3).len == 2
|
||||
e := ',,,0,,,,,a,,b,'
|
||||
assert e.split(',,').len == 5
|
||||
assert e.split_nth(',,', 3).len == 3
|
||||
assert e.split_nth(',', -1).len == 12
|
||||
assert e.split_nth(',', 3).len == 3
|
||||
}
|
||||
|
||||
fn test_split_nth_values() {
|
||||
line := 'CMD=eprintln(phase=1)'
|
||||
|
||||
a0 := line.split_nth('=', 0)
|
||||
assert a0.len == 3
|
||||
assert a0[0] == 'CMD'
|
||||
assert a0[1] == 'eprintln(phase'
|
||||
assert a0[2] == '1)'
|
||||
|
||||
a1 := line.split_nth('=', 1)
|
||||
assert a1.len == 1
|
||||
assert a1[0] == 'CMD=eprintln(phase=1)'
|
||||
|
||||
a2 := line.split_nth('=', 2)
|
||||
assert a2.len == 2
|
||||
assert a2[0] == 'CMD'
|
||||
assert a2[1] == 'eprintln(phase=1)'
|
||||
|
||||
a3 := line.split_nth('=', 3)
|
||||
assert a3.len == 3
|
||||
assert a3[0] == 'CMD'
|
||||
assert a3[1] == 'eprintln(phase'
|
||||
assert a3[2] == '1)'
|
||||
|
||||
a4 := line.split_nth('=', 4)
|
||||
assert a4.len == 3
|
||||
assert a4[0] == 'CMD'
|
||||
assert a4[1] == 'eprintln(phase'
|
||||
assert a4[2] == '1)'
|
||||
}
|
||||
|
||||
fn test_split() {
|
||||
mut s := 'volt/twitch.v:34'
|
||||
mut vals := s.split(':')
|
||||
assert vals.len == 2
|
||||
assert vals[0] == 'volt/twitch.v'
|
||||
assert vals[1] == '34'
|
||||
// /////////
|
||||
s = '2018-01-01z13:01:02'
|
||||
vals = s.split('z')
|
||||
assert vals.len == 2
|
||||
assert vals[0] == '2018-01-01'
|
||||
assert vals[1] == '13:01:02'
|
||||
// //////////
|
||||
s = '4627a862c3dec29fb3182a06b8965e0025759e18___1530207969___blue'
|
||||
vals = s.split('___')
|
||||
assert vals.len == 3
|
||||
assert vals[0] == '4627a862c3dec29fb3182a06b8965e0025759e18'
|
||||
assert vals[1] == '1530207969'
|
||||
assert vals[2] == 'blue'
|
||||
// /////////
|
||||
s = 'lalala'
|
||||
vals = s.split('a')
|
||||
assert vals.len == 4
|
||||
assert vals[0] == 'l'
|
||||
assert vals[1] == 'l'
|
||||
assert vals[2] == 'l'
|
||||
assert vals[3] == ''
|
||||
// /////////
|
||||
s = 'awesome'
|
||||
a := s.split('')
|
||||
assert a.len == 7
|
||||
assert a[0] == 'a'
|
||||
assert a[1] == 'w'
|
||||
assert a[2] == 'e'
|
||||
assert a[3] == 's'
|
||||
assert a[4] == 'o'
|
||||
assert a[5] == 'm'
|
||||
assert a[6] == 'e'
|
||||
// /////////
|
||||
s = 'wavy turquoise bags'
|
||||
vals = s.split(' bags')
|
||||
assert vals.len == 2
|
||||
assert vals[0] == 'wavy turquoise'
|
||||
assert vals[1] == ''
|
||||
}
|
||||
|
||||
/*
|
||||
fn test_trim_space() {
|
||||
a := ' a '
|
||||
assert a.trim_space() == 'a'
|
||||
code := '
|
||||
|
||||
fn main() {
|
||||
println(2)
|
||||
}
|
||||
|
||||
'
|
||||
code_clean := 'fn main() {
|
||||
println(2)
|
||||
}'
|
||||
assert code.trim_space() == code_clean
|
||||
}*/
|
||||
|
||||
/*
|
||||
fn test_join() {
|
||||
mut strings := ['a', 'b', 'c']
|
||||
mut s := strings.join(' ')
|
||||
assert s == 'a b c'
|
||||
strings = [
|
||||
'one
|
||||
two ',
|
||||
'three!
|
||||
four!',
|
||||
]
|
||||
s = strings.join(' ')
|
||||
assert s.contains('one') && s.contains('two ') && s.contains('four')
|
||||
empty := []string{len: 0}
|
||||
assert empty.join('A') == ''
|
||||
}*/
|
||||
|
||||
fn test_clone() {
|
||||
mut a := 'a'
|
||||
a += 'a'
|
||||
a += 'a'
|
||||
b := a
|
||||
c := a.clone()
|
||||
assert c == a
|
||||
assert c == 'aaa'
|
||||
assert b == 'aaa'
|
||||
}
|
||||
|
||||
fn test_replace() {
|
||||
a := 'hello man!'
|
||||
mut b := a.replace('man', 'world')
|
||||
assert b == ('hello world!')
|
||||
b = b.replace('!', '')
|
||||
assert b == ('hello world')
|
||||
b = b.replace('h', 'H')
|
||||
assert b == ('Hello world')
|
||||
b = b.replace('foo', 'bar')
|
||||
assert b == ('Hello world')
|
||||
s := 'hey man how are you'
|
||||
assert s.replace('man ', '') == 'hey how are you'
|
||||
lol := 'lol lol lol'
|
||||
assert lol.replace('lol', 'LOL') == 'LOL LOL LOL'
|
||||
b = 'oneBtwoBBthree'
|
||||
assert b.replace('B', '') == 'onetwothree'
|
||||
b = '*charptr'
|
||||
assert b.replace('charptr', 'byteptr') == '*byteptr'
|
||||
c := 'abc'
|
||||
println(c.replace('', '-'))
|
||||
// assert c.replace('', '-') == c
|
||||
v := 'a b c d'
|
||||
assert v.replace(' ', ' ') == 'a b c d'
|
||||
}
|
||||
|
||||
fn test_replace_each() {
|
||||
s := 'hello man man :)'
|
||||
q := s.replace_each([
|
||||
'man',
|
||||
'dude',
|
||||
'hello',
|
||||
'hey',
|
||||
])
|
||||
assert q == 'hey dude dude :)'
|
||||
bb := '[b]bold[/b] [code]code[/code]'
|
||||
assert bb.replace_each([
|
||||
'[b]',
|
||||
'<b>',
|
||||
'[/b]',
|
||||
'</b>',
|
||||
'[code]',
|
||||
'<code>',
|
||||
'[/code]',
|
||||
'</code>',
|
||||
]) == '<b>bold</b> <code>code</code>'
|
||||
bb2 := '[b]cool[/b]'
|
||||
assert bb2.replace_each([
|
||||
'[b]',
|
||||
'<b>',
|
||||
'[/b]',
|
||||
'</b>',
|
||||
]) == '<b>cool</b>'
|
||||
t := 'aaaaaaaa'
|
||||
y := t.replace_each([
|
||||
'aa',
|
||||
'b',
|
||||
])
|
||||
assert y == 'bbbb'
|
||||
s2 := 'hello_world hello'
|
||||
assert s2.replace_each(['hello_world', 'aaa', 'hello', 'bbb']) == 'aaa bbb'
|
||||
}
|
||||
|
||||
fn test_itoa() {
|
||||
num := 777
|
||||
assert num.str() == '777'
|
||||
big := 7779998
|
||||
assert big.str() == '7779998'
|
||||
a := 3
|
||||
assert a.str() == '3'
|
||||
b := 5555
|
||||
assert b.str() == '5555'
|
||||
zero := 0
|
||||
assert zero.str() == '0'
|
||||
neg := -7
|
||||
assert neg.str() == '-7'
|
||||
}
|
||||
|
||||
fn test_reassign() {
|
||||
a := 'hi'
|
||||
mut b := a
|
||||
b += '!'
|
||||
assert a == 'hi'
|
||||
assert b == 'hi!'
|
||||
}
|
||||
|
||||
/*
|
||||
fn test_runes() {
|
||||
s := 'привет'
|
||||
assert s.len == 12
|
||||
s2 := 'privet'
|
||||
assert s2.len == 6
|
||||
u := s.runes()
|
||||
assert u.len == 6
|
||||
assert s2.substr(1, 4).len == 3
|
||||
assert s2.substr(1, 4) == 'riv'
|
||||
assert s2[1..4].len == 3
|
||||
assert s2[1..4] == 'riv'
|
||||
assert s2[..4].len == 4
|
||||
assert s2[..4] == 'priv'
|
||||
assert s2[2..].len == 4
|
||||
assert s2[2..] == 'ivet'
|
||||
assert u[1..4].string().len == 6
|
||||
assert u[1..4].string() == 'рив'
|
||||
assert s2.substr(1, 2) == 'r'
|
||||
assert u[1..2].string() == 'р'
|
||||
assert s2.runes()[1] == `r`
|
||||
assert u[1] == `р`
|
||||
first := u[0]
|
||||
last := u[u.len - 1]
|
||||
assert first.str().len == 2
|
||||
assert last.str().len == 2
|
||||
}*/
|
||||
|
||||
fn test_contains() {
|
||||
s := 'view.v'
|
||||
assert s.contains('vi')
|
||||
assert !s.contains('random')
|
||||
assert ''.contains('')
|
||||
assert 'abc'.contains('')
|
||||
}
|
||||
|
||||
fn test_contains_any() {
|
||||
assert !'team'.contains_any('i')
|
||||
assert 'fail'.contains_any('ui')
|
||||
assert 'ure'.contains_any('ui')
|
||||
assert 'failure'.contains_any('ui')
|
||||
assert !'foo'.contains_any('')
|
||||
assert !''.contains_any('')
|
||||
}
|
||||
|
||||
fn test_contains_any_substr() {
|
||||
s := 'Some random text'
|
||||
assert s.contains_any_substr(['false', 'not', 'rand'])
|
||||
assert !s.contains_any_substr(['ABC', 'invalid'])
|
||||
assert ''.contains_any_substr([])
|
||||
assert 'abc'.contains_any_substr([''])
|
||||
}
|
||||
|
||||
fn test_arr_contains() {
|
||||
a := ['a', 'b', 'c']
|
||||
assert a.contains('b')
|
||||
ints := [1, 2, 3]
|
||||
assert ints.contains(2)
|
||||
}
|
||||
|
||||
/*
|
||||
fn test_to_num() {
|
||||
s := '7'
|
||||
assert s.int() == 7
|
||||
assert s.byte() == 7
|
||||
assert s.u64() == 7
|
||||
f := '71.5 hasdf'
|
||||
// QTODO
|
||||
assert f.f32() == 71.5
|
||||
vals := ['9']
|
||||
assert vals[0].int() == 9
|
||||
big := '93993993939322'
|
||||
assert big.u64() == 93993993939322
|
||||
assert big.i64() == 93993993939322
|
||||
}*/
|
||||
|
||||
/*
|
||||
fn test_inter_format_string() {
|
||||
float_num := 1.52345
|
||||
float_num_string := '-${float_num:.3f}-'
|
||||
//assert float_num_string == '-1.523-'
|
||||
int_num := 7
|
||||
int_num_string := '-${int_num:03d}-'
|
||||
//assert int_num_string == '-007-'
|
||||
ch := `a`
|
||||
ch_string := '-${ch:c}-'
|
||||
//assert ch_string == '-a-'
|
||||
hex_n := 192
|
||||
hex_n_string := '-${hex_n:x}-'
|
||||
assert hex_n_string == '-c0-'
|
||||
oct_n := 192
|
||||
oct_n_string := '-${oct_n:o}-'
|
||||
assert oct_n_string == '-300-'
|
||||
str := 'abc'
|
||||
str_string := '-${str:s}-'
|
||||
assert str_string == '-abc-'
|
||||
}*/
|
||||
|
||||
/*
|
||||
fn test_hash() {
|
||||
s := '10000'
|
||||
assert s.hash() == 46730161
|
||||
s2 := '24640'
|
||||
assert s2.hash() == 47778736
|
||||
s3 := 'Content-Type'
|
||||
assert s3.hash() == 949037134
|
||||
s4 := 'bad_key'
|
||||
assert s4.hash() == -346636507
|
||||
s5 := '24640'
|
||||
// From a map collision test
|
||||
assert s5.hash() % ((1 << 20) - 1) == s.hash() % ((1 << 20) - 1)
|
||||
assert s5.hash() % ((1 << 20) - 1) == 592861
|
||||
}*/
|
||||
|
||||
fn test_trim() {
|
||||
assert 'banana'.trim('bna') == ''
|
||||
assert 'abc'.trim('ac') == 'b'
|
||||
assert 'aaabccc'.trim('ac') == 'b'
|
||||
}
|
||||
|
||||
fn test_trim_left() {
|
||||
mut s := 'module main'
|
||||
assert s.trim_left(' ') == 'module main'
|
||||
s = ' module main'
|
||||
assert s.trim_left(' ') == 'module main'
|
||||
// test cutset
|
||||
s = 'banana'
|
||||
assert s.trim_left('ba') == 'nana'
|
||||
assert s.trim_left('ban') == ''
|
||||
}
|
||||
|
||||
fn test_trim_right() {
|
||||
mut s := 'module main'
|
||||
assert s.trim_right(' ') == 'module main'
|
||||
s = 'module main '
|
||||
assert s.trim_right(' ') == 'module main'
|
||||
// test cutset
|
||||
s = 'banana'
|
||||
assert s.trim_right('na') == 'b'
|
||||
assert s.trim_right('ban') == ''
|
||||
}
|
||||
|
||||
fn test_all_before() {
|
||||
s := 'fn hello fn'
|
||||
assert s.all_before(' ') == 'fn'
|
||||
assert s.all_before('2') == s
|
||||
assert s.all_before('') == s
|
||||
}
|
||||
|
||||
fn test_all_before_last() {
|
||||
s := 'fn hello fn'
|
||||
assert s.all_before_last(' ') == 'fn hello'
|
||||
assert s.all_before_last('2') == s
|
||||
assert s.all_before_last('') == s
|
||||
}
|
||||
|
||||
fn test_all_after() {
|
||||
s := 'fn hello'
|
||||
assert s.all_after('fn ') == 'hello'
|
||||
assert s.all_after('test') == s
|
||||
assert s.all_after('') == s
|
||||
assert s.after('e') == 'llo'
|
||||
x := s.after('e')
|
||||
assert x == 'llo'
|
||||
}
|
||||
|
||||
fn test_reverse() {
|
||||
println('hello'.reverse())
|
||||
assert 'hello'.reverse() == 'olleh'
|
||||
assert ''.reverse() == ''
|
||||
assert 'a'.reverse() == 'a'
|
||||
}
|
||||
|
||||
fn test_count() {
|
||||
assert ''.count('') == 0
|
||||
assert ''.count('a') == 0
|
||||
assert 'a'.count('') == 0
|
||||
assert 'aa'.count('a') == 2
|
||||
assert 'aa'.count('aa') == 1
|
||||
assert 'aabbaa'.count('aa') == 2
|
||||
assert 'bbaabb'.count('aa') == 1
|
||||
}
|
||||
|
||||
fn test_lower() {
|
||||
mut s := 'A'
|
||||
assert !s.is_lower()
|
||||
assert s.to_lower() == 'a'
|
||||
assert s.to_lower().len == 1
|
||||
s = 'HELLO'
|
||||
assert !s.is_lower()
|
||||
assert s.to_lower() == 'hello'
|
||||
assert s.to_lower().len == 5
|
||||
s = 'Aloha'
|
||||
assert !s.is_lower()
|
||||
assert s.to_lower() == 'aloha'
|
||||
s = 'Have A nice Day!'
|
||||
assert !s.is_lower()
|
||||
assert s.to_lower() == 'have a nice day!'
|
||||
s = 'hi'
|
||||
assert s.is_lower()
|
||||
assert s.to_lower() == 'hi'
|
||||
assert 'aloha!'[0] == `a`
|
||||
assert 'aloha!'[5] == `!`
|
||||
}
|
||||
|
||||
fn test_upper() {
|
||||
mut s := 'a'
|
||||
assert !s.is_upper()
|
||||
assert s.to_upper() == 'A'
|
||||
assert s.to_upper().len == 1
|
||||
s = 'hello'
|
||||
assert !s.is_upper()
|
||||
assert s.to_upper() == 'HELLO'
|
||||
assert s.to_upper().len == 5
|
||||
s = 'Aloha'
|
||||
assert !s.is_upper()
|
||||
assert s.to_upper() == 'ALOHA'
|
||||
s = 'have a nice day!'
|
||||
assert !s.is_upper()
|
||||
assert s.to_upper() == 'HAVE A NICE DAY!'
|
||||
s = 'HI'
|
||||
assert s.is_upper()
|
||||
assert s.to_upper() == 'HI'
|
||||
}
|
||||
|
||||
fn test_capitalize() {
|
||||
mut s := 'hello'
|
||||
assert !s.is_capital()
|
||||
assert s.capitalize() == 'Hello'
|
||||
s = 'test'
|
||||
assert !s.is_capital()
|
||||
assert s.capitalize() == 'Test'
|
||||
s = 'i am ray'
|
||||
assert !s.is_capital()
|
||||
assert s.capitalize() == 'I am ray'
|
||||
s = ''
|
||||
assert !s.is_capital()
|
||||
assert s.capitalize() == ''
|
||||
s = 'TEST IT'
|
||||
assert !s.is_capital()
|
||||
assert s.capitalize() == 'TEST IT'
|
||||
s = 'Test it'
|
||||
assert s.is_capital()
|
||||
assert s.capitalize() == 'Test it'
|
||||
assert 'GameMission_t'.capitalize() == 'GameMission_t'
|
||||
}
|
||||
|
||||
fn test_title() {
|
||||
mut s := 'hello world'
|
||||
assert !s.is_title()
|
||||
assert s.title() == 'Hello World'
|
||||
s = 'HELLO WORLD'
|
||||
assert !s.is_title()
|
||||
assert s.title() == 'HELLO WORLD'
|
||||
s = 'Hello World'
|
||||
assert s.is_title()
|
||||
assert s.title() == 'Hello World'
|
||||
}
|
||||
|
||||
fn test_for_loop() {
|
||||
mut i := 0
|
||||
s := 'abcd'
|
||||
|
||||
for c in s {
|
||||
assert c == s[i]
|
||||
i++
|
||||
}
|
||||
}
|
||||
|
||||
fn test_for_loop_two() {
|
||||
s := 'abcd'
|
||||
|
||||
for i, c in s {
|
||||
assert c == s[i]
|
||||
}
|
||||
}
|
||||
|
||||
fn test_quote() {
|
||||
a := `'`
|
||||
println('testing double quotes')
|
||||
b := 'hi'
|
||||
assert b == 'hi'
|
||||
// assert a.str() == "'"
|
||||
}
|
||||
|
||||
/*
|
||||
fn test_limit() {
|
||||
s := 'hello'
|
||||
assert s.limit(2) == 'he'
|
||||
assert s.limit(9) == s
|
||||
assert s.limit(0) == ''
|
||||
// assert s.limit(-1) == ''
|
||||
}*/
|
||||
|
||||
fn test_repeat() {
|
||||
s1 := 'V! '
|
||||
assert s1.repeat(5) == 'V! V! V! V! V! '
|
||||
assert s1.repeat(1) == s1
|
||||
assert s1.repeat(0) == ''
|
||||
s2 := ''
|
||||
assert s2.repeat(5) == s2
|
||||
assert s2.repeat(1) == s2
|
||||
assert s2.repeat(0) == s2
|
||||
// TODO Add test for negative values
|
||||
}
|
||||
|
||||
fn test_starts_with() {
|
||||
s := 'V Programming Language'
|
||||
assert s.starts_with('V') == true
|
||||
assert s.starts_with('V Programming') == true
|
||||
assert s.starts_with('Language') == false
|
||||
}
|
||||
|
||||
fn test_trim_prefix() {
|
||||
s := 'V Programming Language'
|
||||
assert s.trim_prefix('V ') == 'Programming Language'
|
||||
assert s.trim_prefix('V Programming ') == 'Language'
|
||||
assert s.trim_prefix('Language') == s
|
||||
|
||||
s2 := 'TestTestTest'
|
||||
assert s2.trim_prefix('Test') == 'TestTest'
|
||||
assert s2.trim_prefix('TestTest') == 'Test'
|
||||
|
||||
s3 := '123Test123Test'
|
||||
assert s3.trim_prefix('123') == 'Test123Test'
|
||||
assert s3.trim_prefix('123Test') == '123Test'
|
||||
}
|
||||
|
||||
fn test_trim_suffix() {
|
||||
s := 'V Programming Language'
|
||||
assert s.trim_suffix(' Language') == 'V Programming'
|
||||
assert s.trim_suffix(' Programming Language') == 'V'
|
||||
assert s.trim_suffix('V') == s
|
||||
|
||||
s2 := 'TestTestTest'
|
||||
assert s2.trim_suffix('Test') == 'TestTest'
|
||||
assert s2.trim_suffix('TestTest') == 'Test'
|
||||
|
||||
s3 := '123Test123Test'
|
||||
assert s3.trim_suffix('123') == s3
|
||||
assert s3.trim_suffix('123Test') == '123Test'
|
||||
}
|
||||
|
||||
fn test_raw() {
|
||||
raw := r'raw\nstring'
|
||||
lines := raw.split('\n')
|
||||
println(lines)
|
||||
assert lines.len == 1
|
||||
println('raw string: "$raw"')
|
||||
|
||||
raw2 := r'Hello V\0'
|
||||
assert raw2[7] == `\\`
|
||||
assert raw2[8] == `0`
|
||||
|
||||
raw3 := r'Hello V\x00'
|
||||
assert raw3[7] == `\\`
|
||||
assert raw3[8] == `x`
|
||||
assert raw3[9] == `0`
|
||||
assert raw3[10] == `0`
|
||||
}
|
||||
|
||||
fn test_raw_with_quotes() {
|
||||
raw := r"some'" + r'"thing' // " should be escaped in the generated C code
|
||||
// assert raw[0] == `s`
|
||||
// assert raw[5] == `"`
|
||||
// assert raw[6] == `t`
|
||||
}
|
||||
|
||||
fn test_escape() {
|
||||
a := 10
|
||||
println("\"$a")
|
||||
// assert "\"$a" == '"10'
|
||||
}
|
||||
|
||||
fn test_atoi() {
|
||||
assert '234232'.int() == 234232
|
||||
assert '-9009'.int() == -9009
|
||||
assert '0'.int() == 0
|
||||
for n in -10000 .. 100000 {
|
||||
s := n.str()
|
||||
assert s.int() == n
|
||||
}
|
||||
}
|
||||
|
||||
fn test_raw_inter() {
|
||||
world := 'world'
|
||||
println(world)
|
||||
s := r'hello\n$world'
|
||||
assert s == r'hello\n$world'
|
||||
assert s.contains('$')
|
||||
}
|
||||
|
||||
fn test_c_r() {
|
||||
// This used to break because of r'' and c''
|
||||
c := 42
|
||||
println('$c')
|
||||
r := 50
|
||||
println('$r')
|
||||
}
|
||||
|
||||
fn test_inter_before_comp_if() {
|
||||
s := '123'
|
||||
// This used to break ('123 $....')
|
||||
$if linux {
|
||||
println(s)
|
||||
}
|
||||
assert s == '123'
|
||||
}
|
||||
|
||||
fn test_double_quote_inter() {
|
||||
a := 1
|
||||
b := 2
|
||||
println('$a $b')
|
||||
assert '$a $b' == '1 2'
|
||||
assert '$a $b' == '1 2'
|
||||
}
|
||||
|
||||
fn foo(b byte) byte {
|
||||
return b - 10
|
||||
}
|
||||
|
||||
fn filter(b byte) bool {
|
||||
return b != `a`
|
||||
}
|
||||
|
||||
/*
|
||||
fn test_split_into_lines() {
|
||||
line_content := 'Line'
|
||||
text_crlf := '$line_content\r\n$line_content\r\n$line_content'
|
||||
lines_crlf := text_crlf.split_into_lines()
|
||||
|
||||
assert lines_crlf.len == 3
|
||||
for line in lines_crlf {
|
||||
assert line == line_content
|
||||
}
|
||||
|
||||
text_lf := '$line_content\n$line_content\n$line_content'
|
||||
lines_lf := text_lf.split_into_lines()
|
||||
|
||||
assert lines_lf.len == 3
|
||||
for line in lines_lf {
|
||||
assert line == line_content
|
||||
}
|
||||
}
|
||||
*/
|
||||
fn test_string_literal_with_backslash() {
|
||||
a := 'HelloWorld'
|
||||
assert a == 'HelloWorld'
|
||||
|
||||
b := 'OneTwoThree'
|
||||
assert b == 'OneTwoThree'
|
||||
}
|
||||
|
||||
/*
|
||||
type MyString = string
|
||||
|
||||
fn test_string_alias() {
|
||||
s := MyString('hi')
|
||||
ss := s + '!'
|
||||
}
|
||||
*/
|
||||
|
||||
// sort an array of structs, by their string field values
|
||||
|
||||
struct Ka {
|
||||
s string
|
||||
i int
|
||||
}
|
||||
|
||||
fn test_sorter() {
|
||||
mut arr := [
|
||||
Ka{
|
||||
s: 'bbb'
|
||||
i: 100
|
||||
},
|
||||
Ka{
|
||||
s: 'aaa'
|
||||
i: 101
|
||||
},
|
||||
Ka{
|
||||
s: 'ccc'
|
||||
i: 102
|
||||
},
|
||||
]
|
||||
cmp := fn (a &Ka, b &Ka) int {
|
||||
return compare_strings(a.s, b.s)
|
||||
}
|
||||
arr.sort_with_compare(cmp)
|
||||
assert arr[0].s == 'aaa'
|
||||
assert arr[0].i == 101
|
||||
assert arr[1].s == 'bbb'
|
||||
assert arr[1].i == 100
|
||||
assert arr[2].s == 'ccc'
|
||||
assert arr[2].i == 102
|
||||
}
|
||||
|
||||
fn test_fields() {
|
||||
assert 'a bcde'.fields() == ['a', 'bcde']
|
||||
assert ' sss \t ssss '.fields() == ['sss', 'ssss']
|
||||
assert '\n xyz \t abc def'.fields() == ['xyz', 'abc', 'def']
|
||||
assert 'hello'.fields() == ['hello']
|
||||
assert ''.fields() == []
|
||||
}
|
||||
|
||||
/*
|
||||
fn test_interpolation_after_quoted_variable_still_works() {
|
||||
rr := 'abc'
|
||||
tt := 'xyz'
|
||||
|
||||
// Basic interpolation, no internal quotes
|
||||
yy := 'Replacing $rr with $tt'
|
||||
assert yy == 'Replacing abc with xyz'
|
||||
|
||||
// Interpolation after quoted variable ending with 'r'quote
|
||||
// that may be mistaken with the start of a raw string,
|
||||
// ensure that it is not.
|
||||
ss := 'Replacing "$rr" with "$tt"'
|
||||
assert ss == 'Replacing "abc" with "xyz"'
|
||||
zz := "Replacing '$rr' with '$tt'"
|
||||
assert zz == "Replacing 'abc' with 'xyz'"
|
||||
|
||||
// Interpolation after quoted variable ending with 'c'quote
|
||||
// may be mistaken with the start of a c string, so
|
||||
// check it is not.
|
||||
cc := 'abc'
|
||||
ccc := "Replacing '$cc' with '$tt'"
|
||||
assert ccc == "Replacing 'abc' with 'xyz'"
|
||||
cccq := 'Replacing "$cc" with "$tt"'
|
||||
assert cccq == 'Replacing "abc" with "xyz"'
|
||||
}
|
||||
*/
|
||||
fn test_index_any() {
|
||||
x := 'abcdefghij'
|
||||
assert x.index_any('ef') == 4
|
||||
assert x.index_any('fe') == 4
|
||||
}
|
@ -287,7 +287,11 @@ fn (mut g JsGen) infix_in_not_in_op(node ast.InfixExpr) {
|
||||
g.gen_deref_ptr(node.right_type)
|
||||
g.write(',')
|
||||
g.expr(node.left)
|
||||
g.write('))')
|
||||
g.write(')')
|
||||
if node.op == .not_in {
|
||||
g.write('.valueOf()')
|
||||
}
|
||||
g.write(')')
|
||||
return
|
||||
} else if r_sym.unaliased_sym.kind == .map {
|
||||
g.expr(node.right)
|
||||
|
@ -145,7 +145,7 @@ pub fn gen(files []&ast.File, table &ast.Table, pref &pref.Preferences) string {
|
||||
g.gen_builtin_type_defs()
|
||||
g.writeln('Object.defineProperty(array.prototype,"len", { get: function() {return new int(this.arr.arr.length);}, set: function(l) { this.arr.arr.length = l.valueOf(); } }); ')
|
||||
g.writeln('Object.defineProperty(string.prototype,"len", { get: function() {return new int(this.str.length);}, set: function(l) {/* ignore */ } }); ')
|
||||
g.writeln('Object.defineProperty(map.prototype,"len", { get: function() {return new int(this.map.length);}, set: function(l) { this.map.length = l.valueOf(); } }); ')
|
||||
g.writeln('Object.defineProperty(map.prototype,"len", { get: function() {return new int(this.map.size);}, set: function(l) { this.map.size = l.valueOf(); } }); ')
|
||||
g.writeln('Object.defineProperty(array.prototype,"length", { get: function() {return new int(this.arr.arr.length);}, set: function(l) { this.arr.arr.length = l.valueOf(); } }); ')
|
||||
g.generated_builtin = true
|
||||
}
|
||||
@ -1182,7 +1182,7 @@ fn (mut g JsGen) gen_assign_stmt(stmt ast.AssignStmt, semicolon bool) {
|
||||
g.write('.val')
|
||||
}
|
||||
|
||||
if g.inside_map_set && op == .assign {
|
||||
if false && g.inside_map_set && op == .assign {
|
||||
g.inside_map_set = false
|
||||
g.write(', ')
|
||||
g.expr(val)
|
||||
@ -2338,15 +2338,24 @@ fn (mut g JsGen) gen_index_expr(expr ast.IndexExpr) {
|
||||
|
||||
if expr.is_setter {
|
||||
g.inside_map_set = true
|
||||
g.write('.map.set(')
|
||||
g.write('.getOrSet(')
|
||||
} else {
|
||||
g.write('.map.get(')
|
||||
}
|
||||
g.expr(expr.index)
|
||||
g.write('.\$toJS()')
|
||||
if !expr.is_setter {
|
||||
g.write(')')
|
||||
if expr.is_setter {
|
||||
// g.write(', ${g.to_js_typ_val(left_typ.)')
|
||||
match left_typ.info {
|
||||
ast.Map {
|
||||
g.write(', ${g.to_js_typ_val(left_typ.info.value_type)}')
|
||||
}
|
||||
else {
|
||||
verror('unreachable')
|
||||
}
|
||||
}
|
||||
}
|
||||
g.write(')')
|
||||
} else if left_typ.kind == .string {
|
||||
if expr.is_setter {
|
||||
// TODO: What's the best way to do this?
|
||||
|
Loading…
Reference in New Issue
Block a user