michael@0: /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- michael@0: * vim: set ts=8 sts=4 et sw=4 tw=99: michael@0: */ michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #include "jscntxt.h" michael@0: #include "jscompartment.h" michael@0: #include "jsnum.h" michael@0: #include "jsstr.h" michael@0: michael@0: #include "jsapi-tests/tests.h" michael@0: michael@0: #include "vm/String-inl.h" michael@0: michael@0: using mozilla::ArrayLength; michael@0: michael@0: static const struct TestPair { michael@0: uint32_t num; michael@0: const char *expected; michael@0: } tests[] = { michael@0: { 0, "0" }, michael@0: { 1, "1" }, michael@0: { 2, "2" }, michael@0: { 9, "9" }, michael@0: { 10, "10" }, michael@0: { 15, "15" }, michael@0: { 16, "16" }, michael@0: { 17, "17" }, michael@0: { 99, "99" }, michael@0: { 100, "100" }, michael@0: { 255, "255" }, michael@0: { 256, "256" }, michael@0: { 257, "257" }, michael@0: { 999, "999" }, michael@0: { 1000, "1000" }, michael@0: { 4095, "4095" }, michael@0: { 4096, "4096" }, michael@0: { 9999, "9999" }, michael@0: { 1073741823, "1073741823" }, michael@0: { 1073741824, "1073741824" }, michael@0: { 1073741825, "1073741825" }, michael@0: { 2147483647, "2147483647" }, michael@0: { 2147483648u, "2147483648" }, michael@0: { 2147483649u, "2147483649" }, michael@0: { 4294967294u, "4294967294" }, michael@0: { 4294967295u, "4294967295" }, michael@0: }; michael@0: michael@0: BEGIN_TEST(testIndexToString) michael@0: { michael@0: for (size_t i = 0, sz = ArrayLength(tests); i < sz; i++) { michael@0: uint32_t u = tests[i].num; michael@0: JSString *str = js::IndexToString(cx, u); michael@0: CHECK(str); michael@0: michael@0: if (!js::StaticStrings::hasUint(u)) michael@0: CHECK(cx->compartment()->dtoaCache.lookup(10, u) == str); michael@0: michael@0: bool match = false; michael@0: CHECK(JS_StringEqualsAscii(cx, str, tests[i].expected, &match)); michael@0: CHECK(match); michael@0: } michael@0: michael@0: return true; michael@0: } michael@0: END_TEST(testIndexToString) michael@0: michael@0: BEGIN_TEST(testStringIsIndex) michael@0: { michael@0: for (size_t i = 0, sz = ArrayLength(tests); i < sz; i++) { michael@0: uint32_t u = tests[i].num; michael@0: JSFlatString *str = js::IndexToString(cx, u); michael@0: CHECK(str); michael@0: michael@0: uint32_t n; michael@0: CHECK(str->isIndex(&n)); michael@0: CHECK(u == n); michael@0: } michael@0: michael@0: return true; michael@0: } michael@0: END_TEST(testStringIsIndex) michael@0: michael@0: BEGIN_TEST(testStringToPropertyName) michael@0: { michael@0: uint32_t index; michael@0: michael@0: static const jschar hiChars[] = { 'h', 'i' }; michael@0: JSFlatString *hiStr = NewString(cx, hiChars); michael@0: CHECK(hiStr); michael@0: CHECK(!hiStr->isIndex(&index)); michael@0: CHECK(hiStr->toPropertyName(cx) != nullptr); michael@0: michael@0: static const jschar maxChars[] = { '4', '2', '9', '4', '9', '6', '7', '2', '9', '5' }; michael@0: JSFlatString *maxStr = NewString(cx, maxChars); michael@0: CHECK(maxStr); michael@0: CHECK(maxStr->isIndex(&index)); michael@0: CHECK(index == UINT32_MAX); michael@0: michael@0: static const jschar maxPlusOneChars[] = { '4', '2', '9', '4', '9', '6', '7', '2', '9', '6' }; michael@0: JSFlatString *maxPlusOneStr = NewString(cx, maxPlusOneChars); michael@0: CHECK(maxPlusOneStr); michael@0: CHECK(!maxPlusOneStr->isIndex(&index)); michael@0: CHECK(maxPlusOneStr->toPropertyName(cx) != nullptr); michael@0: michael@0: return true; michael@0: } michael@0: michael@0: template static JSFlatString * michael@0: NewString(JSContext *cx, const jschar (&chars)[N]) michael@0: { michael@0: return js_NewStringCopyN(cx, chars, N); michael@0: } michael@0: michael@0: END_TEST(testStringToPropertyName)