From c012d689259ca6165824226e24983295aa853e05 Mon Sep 17 00:00:00 2001 From: Michal Michalski Date: Fri, 28 Jun 2019 13:23:21 +0200 Subject: [PATCH] [utils][webapi-plugins.spec][common][tizen-wrt.gyp][tizen] Common bundle tests. http://suprem.sec.samsung.net/jira/browse/TWDAPI-225 Tests for common Bundle implementation. [Verification] Pass rate 100%. Signed-off-by: Michal Michalski Change-Id: Ib8ae4415b45f018efc3406c071115782920798f9 --- packaging/webapi-plugins.spec | 18 ++ src/common/common_ut.gyp | 39 +++ src/common/ut/bundle_ut.cc | 372 +++++++++++++++++++++++++++ src/common/ut/common_ut_extension.cc | 28 ++ src/common/ut/common_ut_extension.h | 28 ++ src/tizen-wrt.gyp | 7 + src/tizen/js/ut/bundle_ut.js | 226 ++++++++++++++++ src/utils/js/ut/common_ut.js | 54 ++++ 8 files changed, 772 insertions(+) create mode 100644 src/common/common_ut.gyp create mode 100644 src/common/ut/bundle_ut.cc create mode 100644 src/common/ut/common_ut_extension.cc create mode 100644 src/common/ut/common_ut_extension.h create mode 100644 src/tizen/js/ut/bundle_ut.js create mode 100644 src/utils/js/ut/common_ut.js diff --git a/packaging/webapi-plugins.spec b/packaging/webapi-plugins.spec index 89f1fae7..6a5ddfa3 100644 --- a/packaging/webapi-plugins.spec +++ b/packaging/webapi-plugins.spec @@ -6,6 +6,8 @@ %define crosswalk_extensions tizen-extensions-crosswalk %define crosswalk_extensions_path %{_libdir}/%{crosswalk_extensions} +%define tizen_ut_build 0 + Name: webapi-plugins Version: 2.45 @@ -689,6 +691,9 @@ GYP_OPTIONS="--depth=. -Dtizen=1 -Dextension_build_type=Debug -Dextension_host_o GYP_OPTIONS="$GYP_OPTIONS -Ddisplay_type=%{display_type}" GYP_OPTIONS="$GYP_OPTIONS -Dcrosswalk_extensions_path=%{crosswalk_extensions_path}" +# ut flags +GYP_OPTIONS="$GYP_OPTIONS -Dtizen_ut_build=%{tizen_ut_build}" + # feature flags GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_account_support=%{?tizen_mobile_feature_account_support}" GYP_OPTIONS="$GYP_OPTIONS -Dtizen_feature_alarm_support=%{?tizen_mobile_feature_alarm_support}" @@ -1177,6 +1182,13 @@ install -p -m 644 plugins.json %{buildroot}%{crosswalk_extensions_path}/common/p %if "%{?unified_build}" == "1" || "%{?profile}" == "mobile" mkdir -p %{buildroot}%{crosswalk_extensions_path}/mobile + +# tizen ut mobile +%if "%{?tizen_ut_build}" == "1" +mkdir -p %{buildroot}/usr/bin +install -p -m 755 out/bin_mobile/bundle_ut %{buildroot}/usr/bin/ +%endif + install -p -m 644 out/bin_mobile/libtizen*.so %{buildroot}%{crosswalk_extensions_path}/mobile # execute desc_gentool LD_LIBRARY_PATH=$LD_LIBRARY_PATH:%{buildroot}%{crosswalk_extensions_path}/mobile out/Default/desc_gentool \ @@ -1309,6 +1321,12 @@ fi %{crosswalk_extensions_path}/mobile/plugins.json %manifest webapi-plugins.manifest +# UT files +%if "%{?tizen_ut_build}" == "1" +%license GTEST.BSD-3-Clause +/usr/bin/bundle_ut +%endif + # mobile-extension-emulator %ifarch %{ix86} x86_64 %post mobile-extension-emulator diff --git a/src/common/common_ut.gyp b/src/common/common_ut.gyp new file mode 100644 index 00000000..1ceb42f5 --- /dev/null +++ b/src/common/common_ut.gyp @@ -0,0 +1,39 @@ +{ + 'includes':[ + '../common/common.gypi', + ], + 'targets': [ + { + 'target_name': 'bundle_ut', + 'type': 'executable', + 'dependencies': [ + 'common.gyp:tizen_common' + ], + 'include_dirs': [ + '../googletest/include/', + '../googletest/', + '../googlemock/include/', + '../googlemock/' + ], + 'sources': [ + '../googletest/src/gtest-all.cc', + '../googlemock/src/gmock-all.cc', + 'ut/common_ut_extension.cc', + 'ut/bundle_ut.cc' + ], + 'libraries': [ + '-lbundle', + '-pthread' + ], + 'conditions': [ + ['tizen == 1', { + 'variables': { + 'packages': [ + 'capi-base-common' + ] + } + }] + ] + }, + ], +} diff --git a/src/common/ut/bundle_ut.cc b/src/common/ut/bundle_ut.cc new file mode 100644 index 00000000..5b9c4062 --- /dev/null +++ b/src/common/ut/bundle_ut.cc @@ -0,0 +1,372 @@ +/* + * Copyright (c) 2019 Samsung Electronics Co., Ltd All Rights Reserved + * + * 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 "tizen.h" + +#include "gmock/gmock.h" +#include "gtest/gtest.h" + +#include "bundle.h" +#include "bundle_internal.h" +#include "common/json-utils.h" + +#include +#include +#include + +using namespace std; +using testing::_; +using testing::StrEq; + +namespace { + +template +picojson::value vec2json(vector vec) { + picojson::array array; + for (auto v : vec) { + array.push_back(picojson::value(static_cast(v))); + } + return picojson::value(array); +} + +} // namespace + +MATCHER_P(KeyValStrEq, expected, "match keyval_t string value") { + auto* kv = const_cast(static_cast(arg)); + + if (BUNDLE_TYPE_STR != bundle_keyval_get_type(kv)) { + return false; + } + + void* untyped = nullptr; + size_t size = 0; + + int ret = bundle_keyval_get_basic_val(kv, &untyped, &size); + if (BUNDLE_ERROR_NONE != ret) { + return false; + } + + string value = static_cast(untyped); + return value == expected; +} + +MATCHER_P(KeyValStrArrEq, expected, "match keyval_t string array value") { + auto* kv = const_cast(static_cast(arg)); + + if (BUNDLE_TYPE_STR_ARRAY != bundle_keyval_get_type(kv)) { + return false; + } + + void** untyped = nullptr; + size_t array_size = 0; + size_t* elem_size = nullptr; + + int ret = bundle_keyval_get_array_val(kv, &untyped, &array_size, &elem_size); + if (BUNDLE_ERROR_NONE != ret) { + return false; + } + + if (array_size != expected.size()) { + return false; + } + + char** value = reinterpret_cast(untyped); + for (size_t i = 0; i < array_size; ++i) { + if (string(value[i]) != expected[i]) { + return false; + } + } + + return true; +} + +MATCHER_P(KeyValBytesEq, expected, "match keyval_t bytes value") { + auto* kv = const_cast(static_cast(arg)); + + if (BUNDLE_TYPE_BYTE != bundle_keyval_get_type(kv)) { + return false; + } + + void* untyped = nullptr; + size_t size = 0; + + int ret = bundle_keyval_get_basic_val(kv, &untyped, &size); + if (BUNDLE_ERROR_NONE != ret) { + return false; + } + + if (size != expected.size()) { + return false; + } + + auto bytes = static_cast(untyped); + for (unsigned int i = 0; i < size; ++i) { + if (bytes[i] != expected[i]) { + return false; + } + } + + return true; +} + +MATCHER_P(KeyValBytesArrEq, expected, "match keyval_t bytes array value") { + auto* kv = const_cast(static_cast(arg)); + + if (BUNDLE_TYPE_BYTE_ARRAY != bundle_keyval_get_type(kv)) { + return false; + } + + void** untyped = nullptr; + size_t array_size = 0; + size_t* elem_size = nullptr; + + int ret = bundle_keyval_get_array_val(kv, &untyped, &array_size, &elem_size); + if (BUNDLE_ERROR_NONE != ret) { + return false; + } + + if (array_size != expected.size()) { + return false; + } + + unsigned char** value = reinterpret_cast(untyped); + for (size_t i = 0; i < array_size; ++i) { + for (size_t j = 0; j < elem_size[i]; ++j) { + if (expected[i][j] != value[i][j]) { + return false; + } + } + } + + return true; +} + +class JsonToBundleTest : public testing::Test { + public: + virtual void SetUp() { + bundleData = bundle_create(); + ASSERT_NE(bundleData, nullptr); + } + + virtual void TearDown() { + int ret = bundle_free(bundleData); + ASSERT_EQ(ret, BUNDLE_ERROR_NONE); + } + + // Replacing bundle_keyval_t with void and cast it in matcher is required because + // bundle_keyval_t has only public declaration, not implementation. + // This causes incomplete type error which I couldn't resolve in any other way. + using BundleIterator = void(const char*, const int, const void*, void*); + using BundleIteratorMock = testing::MockFunction; + + void CheckBundle(bundle* b, BundleIteratorMock& mock) { + bundle_foreach(b, + [](const char* key, const int type, const bundle_keyval_t* kv, void* ud) { + auto* mock = static_cast*>(ud); + mock->Call(key, type, kv, nullptr); + }, + &mock); + } + + bundle* bundleData; + BundleIteratorMock bundleIteratorMock; +}; + +TEST_F(JsonToBundleTest, BytesArrayConversion) { + vector> value = {{0, 1, 2}, {100, 101, 102}, {200, 201, 202}}; + + picojson::object json; + picojson::array array; + array.push_back(vec2json(value[0])); + array.push_back(vec2json(value[1])); + array.push_back(vec2json(value[2])); + json["key"] = picojson::value(array); + + auto result = common::JsonToBundle(json, bundleData); + ASSERT_TRUE(result); + + EXPECT_CALL(bundleIteratorMock, + Call(StrEq("key"), BUNDLE_TYPE_BYTE_ARRAY, KeyValBytesArrEq(value), nullptr)); + + CheckBundle(bundleData, bundleIteratorMock); +} + +TEST_F(JsonToBundleTest, BytesConversion) { + vector value = {0, 126, 255}; + + picojson::object json; + json["key"] = vec2json(value); + + auto result = common::JsonToBundle(json, bundleData); + ASSERT_TRUE(result); + + EXPECT_CALL(bundleIteratorMock, + Call(StrEq("key"), BUNDLE_TYPE_BYTE, KeyValBytesEq(value), nullptr)); + + CheckBundle(bundleData, bundleIteratorMock); +} + +TEST_F(JsonToBundleTest, BytesConversionInvalidByteValue) { + picojson::object json; + json["key"] = vec2json(vector({1.0, 256.0, 2.0})); + + auto result = common::JsonToBundle(json, bundleData); + ASSERT_FALSE(result); + + json["key"] = vec2json(vector({1.0, -1.0, 2.0})); + result = common::JsonToBundle(json, bundleData); + ASSERT_FALSE(result); +} + +TEST_F(JsonToBundleTest, StringConversion) { + string value = "tizen"; + picojson::object json; + json["key"] = picojson::value(value); + + auto result = common::JsonToBundle(json, bundleData); + ASSERT_TRUE(result); + + EXPECT_CALL(bundleIteratorMock, Call(StrEq("key"), BUNDLE_TYPE_STR, KeyValStrEq(value), nullptr)); + + CheckBundle(bundleData, bundleIteratorMock); +} + +TEST_F(JsonToBundleTest, StringArrayConversion) { + vector value = {"str1", "str2", "str3"}; + + picojson::object json; + json["key"] = picojson::value(picojson::array( + {picojson::value(value[0]), picojson::value(value[1]), picojson::value(value[2])})); + + auto result = common::JsonToBundle(json, bundleData); + ASSERT_TRUE(result); + + EXPECT_CALL(bundleIteratorMock, + Call(StrEq("key"), BUNDLE_TYPE_STR_ARRAY, KeyValStrArrEq(value), nullptr)); + + CheckBundle(bundleData, bundleIteratorMock); +} + +TEST_F(JsonToBundleTest, UnsupportedType) { + picojson::object json; + json["key"] = picojson::value(true); + + auto result = common::JsonToBundle(json, bundleData); + ASSERT_FALSE(result); + + picojson::object json2; + json["key"] = picojson::value(picojson::object()); + + result = common::JsonToBundle(json, bundleData); + ASSERT_FALSE(result); +} + +class BundleToJsonTest : public testing::Test { + public: + virtual void SetUp() { + bundleData = bundle_create(); + ASSERT_NE(bundleData, nullptr); + } + + virtual void TearDown() { + ASSERT_EQ(bundle_free(bundleData), BUNDLE_ERROR_NONE); + } + + bundle* bundleData; +}; + +TEST_F(BundleToJsonTest, StringConversion) { + string key = "key", value = "tizen"; + ASSERT_EQ(bundle_add_str(bundleData, key.c_str(), value.c_str()), BUNDLE_ERROR_NONE); + + picojson::object json; + auto result = common::BundleToJson(bundleData, &json); + + ASSERT_TRUE(result); + ASSERT_EQ(json[key].get(), value); +} + +TEST_F(BundleToJsonTest, StringArrayConversion) { + string key = "key"; + vector value = {"value1", "value2"}; + + ASSERT_EQ(bundle_add_str_array(bundleData, key.c_str(), value.data(), value.size()), + BUNDLE_ERROR_NONE); + + picojson::object json; + auto result = common::BundleToJson(bundleData, &json); + ASSERT_TRUE(result); + + const auto& array = json[key].get(); + ASSERT_EQ(array.size(), value.size()); + EXPECT_EQ(array[0].get(), std::string(value[0])); + EXPECT_EQ(array[1].get(), std::string(value[1])); +} + +TEST_F(BundleToJsonTest, BytesConversion) { + string key = "key"; + vector bytes = {0, 126, 255}; + + ASSERT_EQ(bundle_add_byte(bundleData, key.c_str(), bytes.data(), bytes.size()), + BUNDLE_ERROR_NONE); + + picojson::object json; + auto result = common::BundleToJson(bundleData, &json); + ASSERT_TRUE(result); + + const auto& array = json[key].get(); + ASSERT_EQ(array.size(), bytes.size()); + EXPECT_EQ(array[0].get(), bytes[0]); + EXPECT_EQ(array[1].get(), bytes[1]); + EXPECT_EQ(array[2].get(), bytes[2]); +} + +TEST_F(BundleToJsonTest, BytesArrayConversion) { + string key = "key"; + vector> value = {{0, 126, 255}, {1, 127, 254}}; + + ASSERT_EQ(bundle_add_byte_array(bundleData, key.c_str(), nullptr, value.size()), + BUNDLE_ERROR_NONE); + ASSERT_EQ( + bundle_set_byte_array_element(bundleData, key.c_str(), 0, value[0].data(), value[0].size()), + BUNDLE_ERROR_NONE); + ASSERT_EQ( + bundle_set_byte_array_element(bundleData, key.c_str(), 1, value[1].data(), value[1].size()), + BUNDLE_ERROR_NONE); + + picojson::object json; + auto result = common::BundleToJson(bundleData, &json); + ASSERT_TRUE(result); + + auto& array = json[key].get(); + ASSERT_EQ(array.size(), value.size()); + + auto& bytes = array[0].get(); + ASSERT_EQ(bytes.size(), value[0].size()); + EXPECT_EQ(bytes[0].get(), value[0][0]); + EXPECT_EQ(bytes[1].get(), value[0][1]); + EXPECT_EQ(bytes[2].get(), value[0][2]); + + bytes = array[1].get(); + ASSERT_EQ(bytes.size(), value[1].size()); + EXPECT_EQ(bytes[0].get(), value[1][0]); + EXPECT_EQ(bytes[1].get(), value[1][1]); + EXPECT_EQ(bytes[2].get(), value[1][2]); +} + +int main(int argc, char* argv[]) { + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} diff --git a/src/common/ut/common_ut_extension.cc b/src/common/ut/common_ut_extension.cc new file mode 100644 index 00000000..f70a17c0 --- /dev/null +++ b/src/common/ut/common_ut_extension.cc @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2019 Samsung Electronics Co., Ltd All Rights Reserved + * + * 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 "common/ut/common_ut_extension.h" + +common::Extension* CreateExtension() { + return new CommonUtExtension; +} + +CommonUtExtension::CommonUtExtension() { + SetExtensionName("tizen"); + SetJavaScriptAPI(""); +} + +CommonUtExtension::~CommonUtExtension() { +} diff --git a/src/common/ut/common_ut_extension.h b/src/common/ut/common_ut_extension.h new file mode 100644 index 00000000..b569b206 --- /dev/null +++ b/src/common/ut/common_ut_extension.h @@ -0,0 +1,28 @@ +/* + * Copyright (c) 2019 Samsung Electronics Co., Ltd All Rights Reserved + * + * 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. + */ + +#ifndef TIZEN_COMMON_UT_EXTENSION_H_ +#define TIZEN_COMMON_UT_EXTENSION_H_ + +#include "common/extension.h" + +class CommonUtExtension : public common::Extension { + public: + CommonUtExtension(); + virtual ~CommonUtExtension(); +}; + +#endif // TIZEN_COMMON_UT_EXTENSION_H_ diff --git a/src/tizen-wrt.gyp b/src/tizen-wrt.gyp index 196dce85..78c12311 100755 --- a/src/tizen-wrt.gyp +++ b/src/tizen-wrt.gyp @@ -14,6 +14,13 @@ 'utils/utils.gyp:*', ], 'conditions': [ + [ + 'tizen_ut_build==1', { + 'dependencies': [ + 'common/common_ut.gyp:*' + ] + } + ], [ 'tizen_feature_account_support==1', { 'dependencies': [ diff --git a/src/tizen/js/ut/bundle_ut.js b/src/tizen/js/ut/bundle_ut.js new file mode 100644 index 00000000..6b03fd26 --- /dev/null +++ b/src/tizen/js/ut/bundle_ut.js @@ -0,0 +1,226 @@ +function TestDefaultCtor() { + var bundle = new tizen.Bundle(); + var counter = 0; + bundle.forEach(function(key, value, type) { + counter++; + }); + assertEqual(0, counter, 'bundle should be empty'); +} + +function TestJsonCtor() { + var json = { + key1: 'value', + key2: ['value1', 'value2'], + key3: new Uint8Array([1, 2, 3]), + key4: [new Uint8Array([1, 2, 3]), new Uint8Array([4, 5, 6])] + }; + + var bundle = new tizen.Bundle(json); + var counter = 0; + forEachOwnProperty(bundle.data, function(k, v) { + counter++; + }); + assertEqual(counter, 4, 'invalid number of entries'); +} + +function TestSetter() { + var bundle = new tizen.Bundle(); + bundle.set('string', 'hello, world'); + assertEqual(bundle.data['string'], 'hello, world', 'invalid string value'); + + bundle.set('stringArray', ['hello', 'world']); + assertArrayEqual( + bundle.data['stringArray'], + ['hello', 'world'], + 'invalid string array value' + ); + + bundle.set('bytes', new Uint8Array([1, 2, 3, 4])); + assertArrayEqual(bundle.data['bytes'], [1, 2, 3, 4], 'invalid bytes value'); + + bundle.set('bytesArray', [new Uint8Array([1, 2, 3]), new Uint8Array([4, 5, 6])]); + assertEqual(bundle.data['bytesArray'].length, 2, 'wrong number of byte streams'); + assertArrayEqual(bundle.data['bytesArray'][0], [1, 2, 3], 'wrong byte stream'); + assertArrayEqual(bundle.data['bytesArray'][1], [4, 5, 6], 'wrong byte stream'); + + bundle.set('other', function() {}); + assertEqual( + bundle.typeOf('other') == tizen.BundleValueType.STRING, + true, + 'other type should be converted to string' + ); + assertEqual(bundle.data['other'], 'function () {}', 'invalid value for other type'); + + bundle.set('someKey', undefined); + assertEqual(bundle.data['someKey'], 'undefined'); +} + +function TestGetters() { + var json = { + key1: 'value', + key2: ['value1', 'value2'], + key3: new Uint8Array([1, 2, 3]), + key4: [new Uint8Array([1, 2, 3]), new Uint8Array([4, 5, 6])] + }; + + var bundle = new tizen.Bundle(json); + + var strVal = bundle.get('key1'); + assertEqual(strVal, 'value', 'string getter returned invalid value'); + + var strArrVal = bundle.get('key2'); + assertArrayEqual( + strArrVal, + ['value1', 'value2'], + 'string array getter returned invalid value' + ); + + var bytesVal = bundle.get('key3'); + assertArrayEqual(bytesVal, [1, 2, 3], 'bytes getter returned invalid value'); + + var bytesArrVal = bundle.get('key4'); + assertEqual(bytesArrVal.length, 2, 'wrong number of byte streams'); + assertArrayEqual(bytesArrVal[0], [1, 2, 3], 'byte stream invalid'); + assertArrayEqual(bytesArrVal[1], [4, 5, 6], 'byte stream invalid'); + + try { + var notVal = bundle.get('not-a-key'); + assertEqual(true, false, 'expected exception was not thrown'); + } catch (err) { + assertEqual(err.code, WebAPIException.NOT_FOUND_ERR, 'expected NOT_FOUND_ERR'); + } +} + +function TestTypeOf() { + var json = { + key1: 'value', + key2: ['value1', 'value2'], + key3: new Uint8Array([1, 2, 3]), + key4: [new Uint8Array([1, 2, 3]), new Uint8Array([4, 5, 6])], + key5: [] + }; + + var bundle = new tizen.Bundle(json); + assertEqual( + bundle.typeOf('key1'), + tizen.BundleValueType.STRING, + 'expected STRING type' + ); + assertEqual( + bundle.typeOf('key2'), + tizen.BundleValueType.STRING_ARRAY, + 'expected STRING_ARRAY type' + ); + assertEqual( + bundle.typeOf('key3'), + tizen.BundleValueType.BYTES, + 'expected BYTES type' + ); + assertEqual( + bundle.typeOf('key4'), + tizen.BundleValueType.BYTES_ARRAY, + 'expected BYTES_ARRAY' + ); + assertEqual( + bundle.typeOf('key5'), + tizen.BundleValueType.STRING_ARRAY, + 'empty array should be treated like STRING_ARRAY' + ); + + try { + type = bundle.typeOf('notKey'); + assertEqual(false, true, 'exception was not thrown'); + } catch (err) { + assertEqual( + err.code, + WebAPIException.NOT_FOUND_ERR, + 'expected NOT_FOUND_ERR exception' + ); + } +} + +function TestForEach() { + var json = { + key1: 'value', + key2: ['value1', 'value2'], + key3: new Uint8Array([1, 2, 3]), + key4: [new Uint8Array([1, 2, 3]), new Uint8Array([4, 5, 6])] + }; + + var bundle = new tizen.Bundle(json); + var assertions = { + key1: { + active: true, + check: function(key, value, type) { + assertEqual(value, 'value', 'invalid value for key ' + key); + assertEqual(type, tizen.BundleValueType.STRING, 'should be STRING'); + } + }, + key2: { + active: true, + check: function(key, value, type) { + assertArrayEqual( + value, + ['value1', 'value2'], + 'invalid value for key ' + key + ); + assertEqual( + type, + tizen.BundleValueType.STRING_ARRAY, + 'should be STRING_ARRAY' + ); + } + }, + key3: { + active: true, + check: function(key, value, type) { + assertArrayEqual(value, [1, 2, 3], 'invalid byte stream'); + assertEqual(type, tizen.BundleValueType.BYTES, 'should be BYTES'); + } + }, + key4: { + active: true, + check: function(key, value, type) { + assertEqual(value.length, 2, 'invalid number of byte streams'); + assertArrayEqual(value[0], [1, 2, 3], 'invalid byte stream'); + assertArrayEqual(value[1], [4, 5, 6], 'invalid byte stream'); + assertEqual(type, tizen.BundleValueType.BYTES_ARRAY); + } + } + }; + + bundle.forEach(function(key, value, type) { + assertEqual(assertions[key].active, true, 'inactive assertion triggered'); + assertions[key].check(key, value, type); + assertions[key].active = false; + }); + + for (var id in assertions) { + if (assertions.hasOwnProperty(id)) { + assertEqual(false, assertions[id].active, 'unused assertion with id ' + id); + } + } +} + +function TestToJson() { + var json = { + key1: 'value', + key2: ['value1', 'value2'], + key3: new Uint8Array([1, 2, 3]), + key4: [new Uint8Array([1, 2, 3]), new Uint8Array([4, 5, 6])] + }; + + var bundle = new tizen.Bundle(json); + result = bundle.toJSON(); + assertEqual(JSON.stringify(json), JSON.stringify(result), 'invalid json'); +} + +var testcases = [ + TestDefaultCtor, + TestJsonCtor, + TestSetter, + TestGetters, + TestTypeOf, + TestForEach, + TestToJson +]; diff --git a/src/utils/js/ut/common_ut.js b/src/utils/js/ut/common_ut.js new file mode 100644 index 00000000..60832dc1 --- /dev/null +++ b/src/utils/js/ut/common_ut.js @@ -0,0 +1,54 @@ +function forEachOwnProperty(obj, cb) { + for (var prop in obj) { + if (obj.hasOwnProperty(prop)) { + cb(prop, obj[prop]); + } + } +} + +function assert(test, condition, message, expected, actual) { + if (!condition) { + throw { + type: 'AssertionError', + where: test, + msg: message, + expected: expected, + actual: actual + }; + } +} + +function assertEqual(a, b, message) { + assert(arguments.callee.caller.name, a == b, message, a, b); +} + +function assertArrayEqual(a, b, message) { + assert( + arguments.callee.caller.name, + a.length == b.length, + message + ' | array size differs', + a.length, + b.length + ); + for (var i = 0; i < a.length; ++i) { + assert( + arguments.callee.caller.name, + a[i] == b[i], + message + ' | array elements not equal at ' + i, + a[i], + b[i] + ); + } +} + +function RunTests(testcases) { + testcases.forEach(function(tc) { + try { + tc(); + console.info(tc.name + ': PASS'); + } catch (err) { + console.info(tc.name + ': FAIL'); + console.error(err); + } + }); +} -- 2.34.1