/* * Copyright (c) 2025 Huawei Device Co., Ltd. * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "ecmascript/tests/test_helper.h" #include "ecmascript/ecma_string.h" #include "common_components/platform/string_hash.h" using namespace panda::ecmascript; using namespace common; namespace panda::test { class EcmaStringHashTest : public BaseTestWithScope { public: template static uint32_t ComputeHashRaw(const T *data, size_t size, uint32_t hashSeed) { uint32_t hash = hashSeed; for (size_t i = 0; i < size; i++) { hash = hash * StringHash::HASH_MULTIPLY + data[i]; } return hash; } template static uint32_t ComputeHashOpt(const T *data, size_t size, uint32_t hashSeed) { return BaseString::ComputeHashForData(data, size, hashSeed); } static uint32_t ComputeConcatHash( const JSThread *thread, const JSHandle &firstString, const JSHandle &secondString) { return EcmaString::CalculateConcatHashCode(thread, firstString, secondString); } }; #if ENABLE_NEXT_OPTIMIZATION /* * @tc.name: ComputeHashForData * @tc.desc: For short data, * test new hashcode compute function result equals original algorithm: hash = hash*31 + data[i] * @tc.type: FUNC */ HWTEST_F_L0(EcmaStringHashTest, ComputeHashForData_001) { std::string data = "Hello World! OpenHarmony"; uint32_t rawHash8 = ComputeHashRaw(reinterpret_cast(data.data()), data.size(), 0); uint32_t optHash8 = ComputeHashOpt(reinterpret_cast(data.data()), data.size(), 0); EXPECT_EQ(rawHash8, optHash8); std::u16string data16 = u"Hello World! 鸿蒙 OpenHarmony"; uint32_t rawHash16 = ComputeHashRaw(reinterpret_cast(data16.data()), data16.size(), 0); uint32_t optHash16 = ComputeHashOpt(reinterpret_cast(data16.data()), data16.size(), 0); EXPECT_EQ(rawHash16, optHash16); } /* * @tc.name: ComputeHashForData * @tc.desc: For medium data, * test new hashcode compute function result equals original algorithm: hash = hash*31 + data[i] * @tc.type: FUNC */ HWTEST_F_L0(EcmaStringHashTest, ComputeHashForData_002) { std::string data = "Hello World! abcdefghijklmnopqrstuvwxyz0123456789 !#$%&'()*+,-./:;=?@[]^_`{|}~"; uint32_t rawHash8 = ComputeHashRaw(reinterpret_cast(data.data()), data.size(), 0); uint32_t optHash8 = ComputeHashOpt(reinterpret_cast(data.data()), data.size(), 0); EXPECT_EQ(rawHash8, optHash8); std::u16string data16 = u"Hello World! abcdefghijklmnopqrstuvwxyz0123456789 !#$%&'()*+,-./:;=?@[]^_`{|}~ 鸿蒙"; uint32_t rawHash16 = ComputeHashRaw(reinterpret_cast(data16.data()), data16.size(), 0); uint32_t optHash16 = ComputeHashOpt(reinterpret_cast(data16.data()), data16.size(), 0); EXPECT_EQ(rawHash16, optHash16); } /* * @tc.name: ComputeHashForData * @tc.desc: For long data, * test new hashcode compute function result equals original algorithm: hash = hash*31 + data[i] * @tc.type: FUNC */ HWTEST_F_L0(EcmaStringHashTest, ComputeHashForData_003) { std::string data = "Hello World! abcdefghijklmnopqrstuvwxyz0123456789 !#$%&'()*+,-./:;=?@[]^_`{|}~"; std::u16string data16 = u"Hello World! abcdefghijklmnopqrstuvwxyz0123456789 !#$%&'()*+,-./:;=?@[]^_`{|}~ 鸿蒙"; for (int i = 0; i < 100; i++) { data += std::to_string(i); std::wstring wstring = std::to_wstring(i); data16 += std::u16string(wstring.begin(), wstring.end()); } uint32_t rawHash8 = ComputeHashRaw(reinterpret_cast(data.data()), data.size(), 0); uint32_t optHash8 = ComputeHashOpt(reinterpret_cast(data.data()), data.size(), 0); EXPECT_EQ(rawHash8, optHash8); uint32_t rawHash16 = ComputeHashRaw(reinterpret_cast(data16.data()), data16.size(), 0); uint32_t optHash16 = ComputeHashOpt(reinterpret_cast(data16.data()), data16.size(), 0); EXPECT_EQ(rawHash16, optHash16); } HWTEST_F_L0(EcmaStringHashTest, CalculateConcatHashCode) { std::string firstData = "Hello World! OpenHarmony"; std::string secondData = "Hello World! OpenHarmony"; JSHandle firstString(thread, EcmaStringAccessor::CreateFromUtf8( instance, reinterpret_cast(firstData.data()), firstData.size(), true)); JSHandle secondString(thread, EcmaStringAccessor::CreateFromUtf8( instance, reinterpret_cast(secondData.data()), secondData.size(), true)); std::string totalString = firstData + secondData; uint32_t totalHash = ComputeHashOpt(reinterpret_cast(totalString.data()), totalString.size(), 0); uint32_t concatHash = ComputeConcatHash(thread, firstString, secondString); EXPECT_EQ(totalHash, concatHash); } #endif }