rm string coercion
This commit is contained in:
315
source/quickjs.c
315
source/quickjs.c
@@ -9514,38 +9514,11 @@ static JSValue JS_ToNumberHintFree(JSContext *ctx, JSValue val,
|
||||
ret = JS_NewInt32(ctx, JS_VALUE_GET_INT(val));
|
||||
break;
|
||||
case JS_TAG_OBJECT:
|
||||
val = JS_ToPrimitiveFree(ctx, val, HINT_NUMBER);
|
||||
if (JS_IsException(val))
|
||||
return JS_EXCEPTION;
|
||||
goto redo;
|
||||
JS_FreeValue(ctx, val);
|
||||
return JS_ThrowTypeError(ctx, "cannot convert object to number");
|
||||
case JS_TAG_STRING:
|
||||
case JS_TAG_STRING_ROPE:
|
||||
{
|
||||
const char *str;
|
||||
const char *p;
|
||||
size_t len;
|
||||
|
||||
str = JS_ToCStringLen(ctx, &len, val);
|
||||
JS_FreeValue(ctx, val);
|
||||
if (!str)
|
||||
return JS_EXCEPTION;
|
||||
p = str;
|
||||
p += skip_spaces(p);
|
||||
if ((p - str) == len) {
|
||||
ret = JS_NewInt32(ctx, 0);
|
||||
} else {
|
||||
int flags = ATOD_ACCEPT_BIN_OCT;
|
||||
ret = js_atof(ctx, p, &p, 0, flags);
|
||||
if (!JS_IsException(ret)) {
|
||||
p += skip_spaces(p);
|
||||
if ((p - str) != len) {
|
||||
JS_FreeValue(ctx, ret);
|
||||
ret = JS_NAN;
|
||||
}
|
||||
}
|
||||
}
|
||||
JS_FreeCString(ctx, str);
|
||||
}
|
||||
ret = JS_NewInt32(ctx,0);
|
||||
break;
|
||||
case JS_TAG_SYMBOL:
|
||||
JS_FreeValue(ctx, val);
|
||||
@@ -10045,16 +10018,7 @@ static JSValue JS_ToStringInternal(JSContext *ctx, JSValueConst val, BOOL is_ToP
|
||||
case JS_TAG_EXCEPTION:
|
||||
return JS_EXCEPTION;
|
||||
case JS_TAG_OBJECT:
|
||||
{
|
||||
JSValue val1, ret;
|
||||
val1 = JS_ToPrimitive(ctx, val, HINT_STRING);
|
||||
if (JS_IsException(val1))
|
||||
return val1;
|
||||
ret = JS_ToStringInternal(ctx, val1, is_ToPropertyKey);
|
||||
JS_FreeValue(ctx, val1);
|
||||
return ret;
|
||||
}
|
||||
break;
|
||||
return JS_AtomToString(ctx, JS_ATOM_true);
|
||||
case JS_TAG_FUNCTION_BYTECODE:
|
||||
return js_new_string8(ctx, "[function bytecode]");
|
||||
case JS_TAG_SYMBOL:
|
||||
@@ -14510,47 +14474,57 @@ static JSValue JS_CallInternal_OLD(JSContext *caller_ctx, JSValueConst func_obj,
|
||||
break;
|
||||
}
|
||||
BREAK;
|
||||
CASE(OP_template_concat):
|
||||
{
|
||||
int n, i;
|
||||
JSValue out;
|
||||
StringBuffer b_s, *b = &b_s;
|
||||
|
||||
CASE(OP_template_concat):
|
||||
{
|
||||
int n, i;
|
||||
JSValue out;
|
||||
StringBuffer b_s, *b = &b_s;
|
||||
n = get_u16(pc);
|
||||
pc += 2;
|
||||
|
||||
n = get_u16(pc);
|
||||
pc += 2;
|
||||
if (n <= 0) {
|
||||
*sp++ = JS_AtomToString(ctx, JS_ATOM_empty_string);
|
||||
BREAK;
|
||||
}
|
||||
|
||||
if (n <= 0) {
|
||||
*sp++ = JS_AtomToString(ctx, JS_ATOM_empty_string);
|
||||
BREAK;
|
||||
}
|
||||
if (string_buffer_init(ctx, b, 64))
|
||||
goto exception;
|
||||
|
||||
if (string_buffer_init(ctx, b, 64))
|
||||
goto exception;
|
||||
for (i = 0; i < n; i++) {
|
||||
JSValue v = sp[i - n];
|
||||
JSValue s = js_cell_text(ctx, JS_NULL, 1, &v);
|
||||
if (JS_IsException(s)) {
|
||||
string_buffer_free(b);
|
||||
for (int j = 0; j < n; j++)
|
||||
JS_FreeValue(ctx, sp[j - n]);
|
||||
sp -= n;
|
||||
goto exception;
|
||||
}
|
||||
if (string_buffer_concat_value_free(b, s)) {
|
||||
string_buffer_free(b);
|
||||
for (int j = 0; j < n; j++)
|
||||
JS_FreeValue(ctx, sp[j - n]);
|
||||
sp -= n;
|
||||
goto exception;
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < n; i++) {
|
||||
JSValue v = sp[i - n];
|
||||
JSValue s = js_cell_text(ctx, JS_NULL, 1, &v);
|
||||
if (JS_IsException(s)) {
|
||||
string_buffer_free(b);
|
||||
goto exception;
|
||||
}
|
||||
if (string_buffer_concat_value_free(b, s)) {
|
||||
string_buffer_free(b);
|
||||
goto exception;
|
||||
}
|
||||
}
|
||||
out = string_buffer_end(b);
|
||||
if (JS_IsException(out)) {
|
||||
for (int j = 0; j < n; j++)
|
||||
JS_FreeValue(ctx, sp[j - n]);
|
||||
sp -= n;
|
||||
goto exception;
|
||||
}
|
||||
|
||||
out = string_buffer_end(b);
|
||||
if (JS_IsException(out))
|
||||
goto exception;
|
||||
for (i = 0; i < n; i++)
|
||||
JS_FreeValue(ctx, sp[i - n]);
|
||||
sp -= n;
|
||||
*sp++ = out;
|
||||
}
|
||||
BREAK;
|
||||
|
||||
for (i = 0; i < n; i++)
|
||||
JS_FreeValue(ctx, sp[i - n]);
|
||||
sp -= n;
|
||||
*sp++ = out;
|
||||
}
|
||||
BREAK;
|
||||
|
||||
CASE(OP_nop):
|
||||
BREAK;
|
||||
@@ -30985,47 +30959,58 @@ static JSValue js_cell_text(JSContext *ctx, JSValueConst this_val,
|
||||
if (argc < 1)
|
||||
return JS_NULL;
|
||||
|
||||
JSValue arg = argv[0];
|
||||
JSValueConst arg = argv[0];
|
||||
int tag = JS_VALUE_GET_TAG(arg);
|
||||
|
||||
/* Handle string */
|
||||
/* Handle string / rope */
|
||||
if (tag == JS_TAG_STRING || tag == JS_TAG_STRING_ROPE) {
|
||||
if (argc == 1)
|
||||
return JS_DupValue(ctx, arg);
|
||||
JSValue str = JS_ToString(ctx, arg); /* owned + flattens rope */
|
||||
if (JS_IsException(str))
|
||||
return JS_EXCEPTION;
|
||||
|
||||
JSString *p = JS_VALUE_GET_STRING(arg);
|
||||
if (argc == 1)
|
||||
return str;
|
||||
|
||||
JSString *p = JS_VALUE_GET_STRING(str);
|
||||
int len = p->len;
|
||||
|
||||
/* text(string, from) - substring from index to end */
|
||||
/* text(string, from, to) - substring */
|
||||
if (argc >= 2 && (JS_VALUE_GET_TAG(argv[1]) == JS_TAG_INT ||
|
||||
JS_VALUE_GET_TAG(argv[1]) == JS_TAG_FLOAT64)) {
|
||||
int from;
|
||||
if (JS_ToInt32(ctx, &from, argv[1]))
|
||||
return JS_NULL;
|
||||
if (argc >= 2) {
|
||||
int tag1 = JS_VALUE_GET_TAG(argv[1]);
|
||||
if (tag1 == JS_TAG_INT || tag1 == JS_TAG_FLOAT64) {
|
||||
int from, to;
|
||||
|
||||
/* Adjust negative index */
|
||||
if (from < 0) from += len;
|
||||
if (from < 0) from = 0;
|
||||
if (from > len) from = len;
|
||||
if (JS_ToInt32(ctx, &from, argv[1])) {
|
||||
JS_FreeValue(ctx, str);
|
||||
return JS_EXCEPTION;
|
||||
}
|
||||
|
||||
int to = len; /* Default: to end of string */
|
||||
if (argc >= 3) {
|
||||
if (JS_ToInt32(ctx, &to, argv[2]))
|
||||
if (from < 0) from += len;
|
||||
if (from < 0) from = 0;
|
||||
if (from > len) from = len;
|
||||
|
||||
to = len;
|
||||
if (argc >= 3) {
|
||||
if (JS_ToInt32(ctx, &to, argv[2])) {
|
||||
JS_FreeValue(ctx, str);
|
||||
return JS_EXCEPTION;
|
||||
}
|
||||
if (to < 0) to += len;
|
||||
if (to < 0) to = 0;
|
||||
if (to > len) to = len;
|
||||
}
|
||||
|
||||
if (from > to) {
|
||||
JS_FreeValue(ctx, str);
|
||||
return JS_NULL;
|
||||
}
|
||||
|
||||
/* Adjust negative index */
|
||||
if (to < 0) to += len;
|
||||
if (to < 0) to = 0;
|
||||
if (to > len) to = len;
|
||||
JSValue sub = js_sub_string(ctx, p, from, to);
|
||||
JS_FreeValue(ctx, str);
|
||||
return sub;
|
||||
}
|
||||
|
||||
if (from > to)
|
||||
return JS_NULL;
|
||||
|
||||
return js_sub_string(ctx, p, from, to);
|
||||
}
|
||||
return JS_DupValue(ctx, arg);
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
/* Handle blob - convert to text representation */
|
||||
@@ -31037,17 +31022,16 @@ static JSValue js_cell_text(JSContext *ctx, JSValueConst this_val,
|
||||
char format = '\0';
|
||||
if (argc > 1) {
|
||||
const char *fmt = JS_ToCString(ctx, argv[1]);
|
||||
if (fmt) {
|
||||
format = fmt[0];
|
||||
JS_FreeCString(ctx, fmt);
|
||||
}
|
||||
if (!fmt)
|
||||
return JS_EXCEPTION;
|
||||
format = fmt[0];
|
||||
JS_FreeCString(ctx, fmt);
|
||||
}
|
||||
|
||||
size_t byte_len = (bd->length + 7) / 8;
|
||||
const uint8_t *data = bd->data;
|
||||
|
||||
if (format == 'h') {
|
||||
/* Hexadecimal encoding */
|
||||
static const char hex[] = "0123456789abcdef";
|
||||
char *result = js_malloc(ctx, byte_len * 2 + 1);
|
||||
if (!result) return JS_EXCEPTION;
|
||||
@@ -31060,65 +31044,61 @@ static JSValue js_cell_text(JSContext *ctx, JSValueConst this_val,
|
||||
js_free(ctx, result);
|
||||
return ret;
|
||||
} else if (format == 'b') {
|
||||
/* Binary encoding */
|
||||
char *result = js_malloc(ctx, bd->length + 1);
|
||||
if (!result) return JS_EXCEPTION;
|
||||
for (size_t i = 0; i < bd->length; i++) {
|
||||
for (size_t i = 0; i < (size_t)bd->length; i++) {
|
||||
size_t byte_idx = i / 8;
|
||||
size_t bit_idx = i % 8;
|
||||
result[i] = (data[byte_idx] & (1 << bit_idx)) ? '1' : '0';
|
||||
result[i] = (data[byte_idx] & (1u << bit_idx)) ? '1' : '0';
|
||||
}
|
||||
result[bd->length] = '\0';
|
||||
JSValue ret = JS_NewString(ctx, result);
|
||||
js_free(ctx, result);
|
||||
return ret;
|
||||
} else if (format == 'o') {
|
||||
/* Octal encoding - 3 bits at a time */
|
||||
size_t octal_len = (bd->length + 2) / 3;
|
||||
size_t octal_len = ((size_t)bd->length + 2) / 3;
|
||||
char *result = js_malloc(ctx, octal_len + 1);
|
||||
if (!result) return JS_EXCEPTION;
|
||||
for (size_t i = 0; i < octal_len; i++) {
|
||||
int val = 0;
|
||||
for (int j = 0; j < 3; j++) {
|
||||
size_t bit_pos = i * 3 + j;
|
||||
if (bit_pos < bd->length) {
|
||||
size_t bit_pos = i * 3 + (size_t)j;
|
||||
if (bit_pos < (size_t)bd->length) {
|
||||
size_t byte_idx = bit_pos / 8;
|
||||
size_t bit_idx = bit_pos % 8;
|
||||
if (data[byte_idx] & (1 << bit_idx))
|
||||
if (data[byte_idx] & (1u << bit_idx))
|
||||
val |= (1 << j);
|
||||
}
|
||||
}
|
||||
result[i] = '0' + val;
|
||||
result[i] = (char)('0' + val);
|
||||
}
|
||||
result[octal_len] = '\0';
|
||||
JSValue ret = JS_NewString(ctx, result);
|
||||
js_free(ctx, result);
|
||||
return ret;
|
||||
} else if (format == 't') {
|
||||
/* Base32 encoding (RFC 4648) */
|
||||
static const char b32[] = "ABCDEFGHIJKLMNOPQRSTUVWXYZ234567";
|
||||
size_t b32_len = (bd->length + 4) / 5;
|
||||
size_t b32_len = ((size_t)bd->length + 4) / 5;
|
||||
char *result = js_malloc(ctx, b32_len + 1);
|
||||
if (!result) return JS_EXCEPTION;
|
||||
for (size_t i = 0; i < b32_len; i++) {
|
||||
int val = 0;
|
||||
for (int j = 0; j < 5; j++) {
|
||||
size_t bit_pos = i * 5 + j;
|
||||
if (bit_pos < bd->length) {
|
||||
size_t bit_pos = i * 5 + (size_t)j;
|
||||
if (bit_pos < (size_t)bd->length) {
|
||||
size_t byte_idx = bit_pos / 8;
|
||||
size_t bit_idx = bit_pos % 8;
|
||||
if (data[byte_idx] & (1 << bit_idx))
|
||||
if (data[byte_idx] & (1u << bit_idx))
|
||||
val |= (1 << j);
|
||||
}
|
||||
}
|
||||
result[i] = b32[val];
|
||||
result[i] = b32[val & 31];
|
||||
}
|
||||
result[b32_len] = '\0';
|
||||
JSValue ret = JS_NewString(ctx, result);
|
||||
js_free(ctx, result);
|
||||
return ret;
|
||||
} else {
|
||||
/* Default: UTF-8 (treat bytes as UTF-8 text) */
|
||||
if (bd->length % 8 != 0)
|
||||
return JS_ThrowTypeError(ctx, "text: blob not byte-aligned for UTF-8");
|
||||
return JS_NewStringLen(ctx, (const char *)data, byte_len);
|
||||
@@ -31132,13 +31112,12 @@ static JSValue js_cell_text(JSContext *ctx, JSValueConst this_val,
|
||||
return JS_EXCEPTION;
|
||||
|
||||
if (argc > 1) {
|
||||
/* Check for radix (number) or format (string) */
|
||||
if (JS_VALUE_GET_TAG(argv[1]) == JS_TAG_INT) {
|
||||
int tag1 = JS_VALUE_GET_TAG(argv[1]);
|
||||
if (tag1 == JS_TAG_INT) {
|
||||
int radix = JS_VALUE_GET_INT(argv[1]);
|
||||
return js_cell_number_to_radix_string(ctx, num, radix);
|
||||
}
|
||||
if (JS_VALUE_GET_TAG(argv[1]) == JS_TAG_STRING ||
|
||||
JS_VALUE_GET_TAG(argv[1]) == JS_TAG_STRING_ROPE) {
|
||||
if (tag1 == JS_TAG_STRING || tag1 == JS_TAG_STRING_ROPE) {
|
||||
const char *format = JS_ToCString(ctx, argv[1]);
|
||||
if (!format) return JS_EXCEPTION;
|
||||
JSValue result = js_cell_format_number(ctx, num, format);
|
||||
@@ -31157,10 +31136,12 @@ static JSValue js_cell_text(JSContext *ctx, JSValueConst this_val,
|
||||
return JS_EXCEPTION;
|
||||
|
||||
const char *separator = "";
|
||||
if (argc > 1 && (JS_VALUE_GET_TAG(argv[1]) == JS_TAG_STRING ||
|
||||
JS_VALUE_GET_TAG(argv[1]) == JS_TAG_STRING_ROPE)) {
|
||||
BOOL sep_alloc = FALSE;
|
||||
|
||||
if (argc > 1 && JS_VALUE_IS_TEXT(argv[1])) {
|
||||
separator = JS_ToCString(ctx, argv[1]);
|
||||
if (!separator) return JS_EXCEPTION;
|
||||
sep_alloc = TRUE;
|
||||
}
|
||||
|
||||
StringBuffer b_s, *b = &b_s;
|
||||
@@ -31168,30 +31149,36 @@ static JSValue js_cell_text(JSContext *ctx, JSValueConst this_val,
|
||||
|
||||
for (int64_t i = 0; i < len; i++) {
|
||||
if (i > 0 && separator[0]) {
|
||||
if (string_buffer_puts8(b, separator)) {
|
||||
string_buffer_free(b);
|
||||
if (argc > 1) JS_FreeCString(ctx, separator);
|
||||
return JS_EXCEPTION;
|
||||
}
|
||||
if (string_buffer_puts8(b, separator))
|
||||
goto array_fail;
|
||||
}
|
||||
JSValue item = JS_GetPropertyInt64(ctx, arg, i);
|
||||
if (JS_IsException(item)) {
|
||||
string_buffer_free(b);
|
||||
if (argc > 1) JS_FreeCString(ctx, separator);
|
||||
return JS_EXCEPTION;
|
||||
}
|
||||
if (!JS_VALUE_IS_TEXT(item))
|
||||
return JS_ThrowInternalError(ctx, "Array must be made of strings.");
|
||||
|
||||
if (string_buffer_concat_value_free(b, item)) {
|
||||
string_buffer_free(b);
|
||||
if (argc > 1) JS_FreeCString(ctx, separator);
|
||||
return JS_EXCEPTION;
|
||||
JSValue item = JS_GetPropertyInt64(ctx, arg, i);
|
||||
if (JS_IsException(item))
|
||||
goto array_fail;
|
||||
|
||||
if (!JS_VALUE_IS_TEXT(item)) {
|
||||
JS_FreeValue(ctx, item);
|
||||
JS_ThrowInternalError(ctx, "Array must be made of strings.");
|
||||
goto array_fail;
|
||||
}
|
||||
|
||||
JSValue item_str = JS_ToString(ctx, item); /* owned + flattens */
|
||||
JS_FreeValue(ctx, item);
|
||||
if (JS_IsException(item_str))
|
||||
goto array_fail;
|
||||
|
||||
if (string_buffer_concat_value_free(b, item_str))
|
||||
goto array_fail;
|
||||
}
|
||||
|
||||
if (argc > 1) JS_FreeCString(ctx, separator);
|
||||
if (sep_alloc) JS_FreeCString(ctx, separator);
|
||||
return string_buffer_end(b);
|
||||
|
||||
array_fail:
|
||||
string_buffer_free(b);
|
||||
if (sep_alloc) JS_FreeCString(ctx, separator);
|
||||
return JS_EXCEPTION;
|
||||
}
|
||||
|
||||
/* Handle function - return source or native stub */
|
||||
@@ -31199,45 +31186,45 @@ static JSValue js_cell_text(JSContext *ctx, JSValueConst this_val,
|
||||
JSObject *p = JS_VALUE_GET_OBJ(arg);
|
||||
if (js_class_has_bytecode(p->class_id)) {
|
||||
JSFunctionBytecode *b = p->u.func.function_bytecode;
|
||||
if (b->has_debug && b->debug.source) {
|
||||
if (b->has_debug && b->debug.source)
|
||||
return JS_NewStringLen(ctx, b->debug.source, b->debug.source_len);
|
||||
}
|
||||
}
|
||||
/* Native function - generate stub */
|
||||
|
||||
const char *pref = "function ";
|
||||
const char *suff = "() {\n [native code]\n}";
|
||||
const char *name = NULL;
|
||||
const char *name = "";
|
||||
const char *name_cstr = NULL;
|
||||
|
||||
JSObject *fp = JS_VALUE_GET_OBJ(arg);
|
||||
if (js_class_has_bytecode(fp->class_id)) {
|
||||
JSFunctionBytecode *fb = fp->u.func.function_bytecode;
|
||||
name = JS_AtomToCString(ctx, fb->func_name);
|
||||
name_cstr = JS_AtomToCString(ctx, fb->func_name);
|
||||
if (name_cstr)
|
||||
name = name_cstr;
|
||||
}
|
||||
if (!name) name = "";
|
||||
|
||||
size_t plen = strlen(pref);
|
||||
size_t nlen = strlen(name);
|
||||
size_t slen = strlen(suff);
|
||||
|
||||
char *result = js_malloc(ctx, plen + nlen + slen + 1);
|
||||
if (!result) {
|
||||
if (name[0]) JS_FreeCString(ctx, name);
|
||||
if (name_cstr) JS_FreeCString(ctx, name_cstr);
|
||||
return JS_EXCEPTION;
|
||||
}
|
||||
|
||||
memcpy(result, pref, plen);
|
||||
memcpy(result + plen, name, nlen);
|
||||
memcpy(result + plen + nlen, suff, slen + 1);
|
||||
|
||||
JSValue ret = JS_NewString(ctx, result);
|
||||
js_free(ctx, result);
|
||||
if (name[0]) JS_FreeCString(ctx, name);
|
||||
if (name_cstr) JS_FreeCString(ctx, name_cstr);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Handle null */
|
||||
// if (JS_IsNull(arg))
|
||||
// return JS_NULL;
|
||||
|
||||
if (JS_IsObject(arg))
|
||||
return JS_NewString(ctx, "[object]");
|
||||
|
||||
return JS_ThrowInternalError(ctx, "Could not convert to text. Tag is %d", JS_VALUE_GET_TAG(arg));
|
||||
return JS_ToString(ctx, arg);
|
||||
return JS_ThrowInternalError(ctx, "Could not convert to text. Tag is %d", tag);
|
||||
}
|
||||
|
||||
/* text.lower(str) - convert to lowercase */
|
||||
|
||||
2
test.ce
2
test.ce
@@ -324,7 +324,7 @@ function run_tests(package_name, specific_test) {
|
||||
} catch (e) {
|
||||
test_entry.status = "failed"
|
||||
test_entry.error = {
|
||||
message: e.toString(),
|
||||
message: e,
|
||||
stack: e.stack || ""
|
||||
}
|
||||
if (e.name) test_entry.error.name = e.name
|
||||
|
||||
@@ -145,7 +145,7 @@ return {
|
||||
if (!caught) throw "string + boolean should throw"
|
||||
},
|
||||
|
||||
/* test_null_plus_string_throws: function() {
|
||||
test_null_plus_string_throws: function() {
|
||||
var caught = false
|
||||
try {
|
||||
var x = null + "hello"
|
||||
@@ -164,7 +164,7 @@ return {
|
||||
}
|
||||
if (!caught) throw "string + null should throw"
|
||||
},
|
||||
*/
|
||||
|
||||
// ============================================================================
|
||||
// COMPARISON OPERATORS
|
||||
// ============================================================================
|
||||
@@ -1076,14 +1076,14 @@ return {
|
||||
if (parent.x != 10) throw "meme should not mutate parent"
|
||||
},
|
||||
|
||||
/* test_meme_multiple_mixins: function() {
|
||||
test_meme_multiple_mixins: function() {
|
||||
var parent = {a: 1}
|
||||
var mixin1 = {b: 2}
|
||||
var mixin2 = {c: 3}
|
||||
var child = meme(parent, mixin1, mixin2)
|
||||
if (child.a != 1 || child.b != 2 || child.c != 3) throw "meme multiple mixins failed"
|
||||
},
|
||||
*/
|
||||
|
||||
// ============================================================================
|
||||
// GLOBAL FUNCTIONS - PROTO
|
||||
// ============================================================================
|
||||
@@ -1551,12 +1551,12 @@ return {
|
||||
if (search(str, "world") != 6) throw "string search failed"
|
||||
if (search(str, "xyz") != null) throw "string search not found failed"
|
||||
},
|
||||
/*
|
||||
|
||||
test_string_lastIndexOf: function() {
|
||||
var str = "hello hello"
|
||||
if (search(str, "hello", 0, true) != 6) throw "string lastSearch failed"
|
||||
},
|
||||
*/
|
||||
|
||||
test_string_toLowerCase: function() {
|
||||
var str = "HELLO"
|
||||
if (lower(str) != "hello") throw "string toLowerCase failed"
|
||||
@@ -1842,7 +1842,7 @@ return {
|
||||
var result = a[null]
|
||||
if (result != null) throw "array get with null key should return null"
|
||||
},
|
||||
/*
|
||||
|
||||
test_obj_get_number_key_returns_null: function() {
|
||||
var o = {a: 1}
|
||||
var result = o[5]
|
||||
@@ -1892,7 +1892,7 @@ return {
|
||||
}
|
||||
if (!caught) throw "setting property on function should throw"
|
||||
},
|
||||
*/
|
||||
|
||||
test_function_bracket_access_throws: function() {
|
||||
var fn = function() {}
|
||||
var caught = false
|
||||
@@ -2188,7 +2188,7 @@ return {
|
||||
var result = reduce(arr, (a, b) => a + b)
|
||||
if (result != "abc") throw "reduce string concat failed"
|
||||
},
|
||||
/*
|
||||
|
||||
test_reduce_to_object: function() {
|
||||
var arr = ["a", "b", "c"]
|
||||
var result = reduce(arr, (obj, val, i) => {
|
||||
@@ -2197,7 +2197,7 @@ return {
|
||||
}, {})
|
||||
if (result.a != 0 || result.b != 1 || result.c != 2) throw "reduce to object failed"
|
||||
},
|
||||
*/
|
||||
|
||||
// ============================================================================
|
||||
// SORT FUNCTION
|
||||
// ============================================================================
|
||||
@@ -2394,12 +2394,12 @@ return {
|
||||
test_abs_float: function() {
|
||||
if (abs(-3.14) != 3.14) throw "abs float failed"
|
||||
},
|
||||
/*
|
||||
|
||||
test_abs_non_number: function() {
|
||||
if (abs("5") != null) throw "abs non-number should return null"
|
||||
if (abs(null) != null) throw "abs null should return null"
|
||||
},
|
||||
*/
|
||||
|
||||
// ============================================================================
|
||||
// FLOOR FUNCTION
|
||||
// ============================================================================
|
||||
@@ -2419,7 +2419,7 @@ return {
|
||||
test_floor_zero: function() {
|
||||
if (floor(0) != 0) throw "floor zero failed"
|
||||
},
|
||||
/*
|
||||
|
||||
test_floor_with_place: function() {
|
||||
if (floor(12.3775, -2) != 12.37) throw "floor with place failed"
|
||||
},
|
||||
@@ -2427,7 +2427,7 @@ return {
|
||||
test_floor_negative_with_place: function() {
|
||||
if (floor(-12.3775, -2) != -12.38) throw "floor negative with place failed"
|
||||
},
|
||||
*/
|
||||
|
||||
// ============================================================================
|
||||
// CEILING FUNCTION
|
||||
// ============================================================================
|
||||
@@ -2447,7 +2447,7 @@ return {
|
||||
test_ceiling_zero: function() {
|
||||
if (ceiling(0) != 0) throw "ceiling zero failed"
|
||||
},
|
||||
/*
|
||||
|
||||
test_ceiling_with_place: function() {
|
||||
if (ceiling(12.3775, -2) != 12.38) throw "ceiling with place failed"
|
||||
},
|
||||
@@ -2471,7 +2471,7 @@ return {
|
||||
test_round_half: function() {
|
||||
if (round(3.5) != 4) throw "round half failed"
|
||||
},
|
||||
*/
|
||||
|
||||
test_round_negative: function() {
|
||||
if (round(-3.5) != -3 && round(-3.5) != -4) throw "round negative failed"
|
||||
},
|
||||
@@ -2479,7 +2479,7 @@ return {
|
||||
test_round_integer: function() {
|
||||
if (round(5) != 5) throw "round integer failed"
|
||||
},
|
||||
/*
|
||||
|
||||
test_round_with_places: function() {
|
||||
if (round(12.3775, -2) != 12.38) throw "round with places failed"
|
||||
},
|
||||
@@ -2487,7 +2487,7 @@ return {
|
||||
test_round_to_tens: function() {
|
||||
if (round(12.3775, 1) != 10) throw "round to tens failed"
|
||||
},
|
||||
*/
|
||||
|
||||
// ============================================================================
|
||||
// TRUNC FUNCTION
|
||||
// ============================================================================
|
||||
@@ -2507,7 +2507,7 @@ return {
|
||||
test_trunc_zero: function() {
|
||||
if (trunc(0) != 0) throw "trunc zero failed"
|
||||
},
|
||||
/*
|
||||
|
||||
test_trunc_with_places: function() {
|
||||
if (trunc(12.3775, -2) != 12.37) throw "trunc with places failed"
|
||||
},
|
||||
@@ -2515,7 +2515,7 @@ return {
|
||||
test_trunc_negative_with_places: function() {
|
||||
if (trunc(-12.3775, -2) != -12.37) throw "trunc negative with places failed"
|
||||
},
|
||||
*/
|
||||
|
||||
// ============================================================================
|
||||
// SIGN FUNCTION
|
||||
// ============================================================================
|
||||
@@ -2536,11 +2536,11 @@ return {
|
||||
if (sign(0.001) != 1) throw "sign positive float failed"
|
||||
if (sign(-0.001) != -1) throw "sign negative float failed"
|
||||
},
|
||||
/*
|
||||
|
||||
test_sign_non_number: function() {
|
||||
if (sign("5") != null) throw "sign non-number should return null"
|
||||
},
|
||||
*/
|
||||
|
||||
// ============================================================================
|
||||
// WHOLE AND FRACTION FUNCTIONS
|
||||
// ============================================================================
|
||||
@@ -2556,7 +2556,7 @@ return {
|
||||
test_whole_integer: function() {
|
||||
if (whole(5) != 5) throw "whole integer failed"
|
||||
},
|
||||
/*
|
||||
|
||||
test_whole_non_number: function() {
|
||||
if (whole("5") != null) throw "whole non-number should return null"
|
||||
},
|
||||
@@ -2565,7 +2565,7 @@ return {
|
||||
var f = fraction(3.75)
|
||||
if (f < 0.74 || f > 0.76) throw "fraction positive failed: " + f
|
||||
},
|
||||
*/
|
||||
|
||||
test_fraction_negative: function() {
|
||||
var f = fraction(-3.75)
|
||||
if (f > -0.74 || f < -0.76) throw "fraction negative failed: " + f
|
||||
@@ -2574,11 +2574,11 @@ return {
|
||||
test_fraction_integer: function() {
|
||||
if (fraction(5) != 0) throw "fraction integer failed"
|
||||
},
|
||||
/*
|
||||
|
||||
test_fraction_non_number: function() {
|
||||
if (fraction("5") != null) throw "fraction non-number should return null"
|
||||
},
|
||||
*/
|
||||
|
||||
// ============================================================================
|
||||
// NEG FUNCTION
|
||||
// ============================================================================
|
||||
@@ -2598,11 +2598,11 @@ return {
|
||||
test_neg_float: function() {
|
||||
if (neg(3.14) != -3.14) throw "neg float failed"
|
||||
},
|
||||
/*
|
||||
|
||||
test_neg_non_number: function() {
|
||||
if (neg("5") != null) throw "neg non-number should return null"
|
||||
},
|
||||
*/
|
||||
|
||||
// ============================================================================
|
||||
// MODULO FUNCTION
|
||||
// ============================================================================
|
||||
@@ -2662,12 +2662,12 @@ return {
|
||||
test_min_float: function() {
|
||||
if (min(3.14, 2.71) != 2.71) throw "min float failed"
|
||||
},
|
||||
/*
|
||||
|
||||
test_min_non_number: function() {
|
||||
if (min(3, "5") != null) throw "min non-number should return null"
|
||||
if (min("3", 5) != null) throw "min first non-number should return null"
|
||||
},
|
||||
*/
|
||||
|
||||
test_max_basic: function() {
|
||||
if (max(3, 5) != 5) throw "max basic failed"
|
||||
},
|
||||
@@ -2687,11 +2687,11 @@ return {
|
||||
test_max_float: function() {
|
||||
if (max(3.14, 2.71) != 3.14) throw "max float failed"
|
||||
},
|
||||
/*
|
||||
|
||||
test_max_non_number: function() {
|
||||
if (max(3, "5") != null) throw "max non-number should return null"
|
||||
},
|
||||
*/
|
||||
|
||||
test_min_max_constrain: function() {
|
||||
var val = 8
|
||||
var constrained = min(max(val, 0), 10)
|
||||
@@ -2859,12 +2859,12 @@ return {
|
||||
test_text_number_negative: function() {
|
||||
if (text(-456) != "-456") throw "text number negative failed"
|
||||
},
|
||||
/*
|
||||
|
||||
test_text_number_float: function() {
|
||||
var result = text(3.14)
|
||||
if (search(result, "3.14") != 0) throw "text number float failed"
|
||||
},
|
||||
*/
|
||||
|
||||
test_text_array_join: function() {
|
||||
var result = text([1, 2, 3], ",")
|
||||
if (result != "1,2,3") throw "text array join failed"
|
||||
@@ -3289,13 +3289,13 @@ return {
|
||||
var result = array(arr, (x, i) => `${x}${i}`)
|
||||
if (result[0] != "a0" || result[1] != "b1") throw "array map with index failed"
|
||||
},
|
||||
/*
|
||||
|
||||
test_array_map_reverse: function() {
|
||||
var arr = [1, 2, 3]
|
||||
var result = array(arr, x => x * 2, true)
|
||||
if (result[0] != 6 || result[2] != 2) throw "array map reverse failed"
|
||||
},
|
||||
*/
|
||||
|
||||
test_array_map_with_exit: function() {
|
||||
var arr = [1, 2, 3, 4, 5]
|
||||
var result = array(arr, x => {
|
||||
|
||||
Reference in New Issue
Block a user