interop test] interface fn returns value

Issue: https://gitee.com/openharmony/arkcompiler_runtime_core/issues/IAY7VY
All tests passed

Signed-off-by: ignatenkooleg <ignatenko.oleg@huawei-partners.com>
This commit is contained in:
ignatenkooleg 2024-10-19 14:18:57 +03:00
parent 97162c83a7
commit 037967a65c
15 changed files with 1195 additions and 0 deletions

View File

@ -0,0 +1 @@
add_subdirectory(interface_method_returns_value)

View File

@ -0,0 +1,3 @@
arktsconfig.json
*.abc
node_modules

View File

@ -0,0 +1,15 @@
# Copyright (c) 2024 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.
add_subdirectory(arkts_interface)
add_subdirectory(js_interface)

View File

@ -0,0 +1,21 @@
# Copyright (c) 2024 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.
set(ETS_CONFIG ${CMAKE_CURRENT_BINARY_DIR}/arktsconfig.json)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/arktsconfig.in.json ${ETS_CONFIG})
panda_ets_interop_js_gtest(ets_interop_js_arkts_calls_js_interface_method__arkts_interfaces
CPP_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/test.cpp
ETS_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/test.sts
ETS_CONFIG ${ETS_CONFIG}
)

View File

@ -0,0 +1,24 @@
{
"compilerOptions": {
"baseUrl": "${PANDA_ROOT}",
"paths": {
"escompat": ["${PANDA_ROOT}/plugins/ets/stdlib/escompat"],
"std": ["${PANDA_ROOT}/plugins/ets/stdlib/std"],
".": [
"${CMAKE_CURRENT_SOURCE_DIR}/index.js",
"${CMAKE_CURRENT_SOURCE_DIR}/index.d.ts"],
"types": ["${CMAKE_CURRENT_SOURCE_DIR}/index.d.ts"]
},
"dynamicPaths": {
"${CMAKE_CURRENT_SOURCE_DIR}/index.js": {
"language": "js",
"hasDecl": false
},
"${CMAKE_CURRENT_SOURCE_DIR}/index.d.ts": {
"language": "js",
"hasDecl": true
}
}
}
}

View File

@ -0,0 +1,105 @@
/**
* Copyright (c) 2023-2024 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.
*/
'use strict';
Object.defineProperty(exports, '__esModule', { value: true });
exports.getUnion = exports.getRefTypeReturn = exports.getRecordTypeReturn = exports.getNativeArrayReturn =
exports.getLiteralTypeReturn = exports.test = void 0;
const etsVm = require('lib/module/ets_interop_js_napi');
const TestModule = /** @class */ (function () {
function TestModule(name) {
this.descriptorPrefix = 'L' + name.replaceAll('.', '/') + '/';
}
TestModule.prototype.getClass = function (name) { return etsVm.getClass(this.descriptorPrefix + name + ';'); };
TestModule.prototype.getFunction = function (name) {
return etsVm.getFunction(this.descriptorPrefix + 'ETSGLOBAL;', name);
};
return TestModule;
}());
function getTestModule(name) { return new TestModule(name); }
const testModule = getTestModule('interface_method_return_value');
function test() {
let ahcGetter = testModule.getFunction('getThroughInterface');
let lol = ahcGetter();
let directClass = testModule.getClass('InstanceClass');
let dir = new directClass();
return true;
}
exports.test = test;
function getLiteralTypeReturn() {
let getterFn = testModule.getFunction('getBoolValue');
let classInstance = getterFn();
let expectedFalse = classInstance.getBoolean();
return typeof expectedFalse === 'boolean' && !expectedFalse;
}
exports.getLiteralTypeReturn = getLiteralTypeReturn;
function getNativeArrayReturn() {
let getterFn = testModule.getFunction('getArrayValue');
let classInstance = getterFn();
let result = classInstance.getArray();
let destructuredFirst = result[0];
let canDestructureCorrectly = destructuredFirst === result[0];
return Array.isArray(result) && canDestructureCorrectly;
}
exports.getNativeArrayReturn = getNativeArrayReturn;
function getRecordTypeReturn() {
let getterFn = testModule.getFunction('getRefValue');
let classInstance = getterFn();
let returnedRecord = classInstance.getRecord();
let shouldBeValidFirst = returnedRecord[0][0] === 'child_0';
let isMissingOptionUndefined = returnedRecord[1];
return shouldBeValidFirst && isMissingOptionUndefined;
}
exports.getRecordTypeReturn = getRecordTypeReturn;
function getRefTypeReturn() {
let getterFn = testModule.getFunction('getRefValue');
let classInstance = getterFn();
let canGetInterfaceMethod = Boolean(classInstance.getLiteral) && typeof classInstance.getLiteral === 'function';
let canGetNotDescribedMethod = Boolean(classInstance.methodNotDeclaredInInterface);
let failsOnInexistentMethod = false;
try {
classInstance.methodYouDontHave();
}
catch (_a) {
failsOnInexistentMethod = true;
}
return canGetInterfaceMethod && canGetNotDescribedMethod && failsOnInexistentMethod;
}
exports.getRefTypeReturn = getRefTypeReturn;
function getUnion() {
let getterFn = testModule.getFunction('getUnion');
// @ts-ignore
let instance = getterFn();
let foundResults = [];
while (!foundResults.includes(1234) && !foundResults.includes(false) && !foundResults.includes('stringValue')) {
let runResult = instance.getUnion();
console.log(runResult);
if (!foundResults.includes(runResult)) {
foundResults.push(runResult);
}
}
return true;
}
exports.getUnion = getUnion;

View File

@ -0,0 +1,90 @@
/**
* Copyright (c) 2024 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.
*/
const etsVm = require('lib/module/ets_interop_js_napi');
class TestModule {
descriptorPrefix: string;
constructor(name) {
this.descriptorPrefix = 'L' + name.replaceAll('.', '/') + '/';
}
getClass(name) { return etsVm.getClass(this.descriptorPrefix + name + ';'); }
getFunction(name) { return etsVm.getFunction(this.descriptorPrefix + 'ETSGLOBAL;', name); }
static descriptorPrefix;
};
function getTestModule(name) { return new TestModule(name); }
const testModule = getTestModule('interface_method_return_value')
export function test(){
const ahcGetter = testModule.getFunction('getThroughInterface');
const lol = ahcGetter();
const directClass = testModule.getClass('InstanceClass');
const dir = new directClass();
return true
}
export function getLiteralTypeReturn(){
const getterFn = testModule.getFunction('getBoolValue');
const classInstance = getterFn();
const expectedFalse = classInstance.getBoolean();
return typeof expectedFalse === 'boolean' && !expectedFalse;
}
export function getNativeArrayReturn(){
const getterFn = testModule.getFunction('getArrayValue');
const classInstance = getterFn();
const result = classInstance.getArray();
const [ destructuredFirst ] = result;
const canDestructureCorrectly = destructuredFirst === result[0]
return Array.isArray(result) && canDestructureCorrectly;
}
export function getRecordTypeReturn(){
const getterFn = testModule.getFunction('getRefValue');
const classInstance = getterFn();
const returnedRecord = classInstance.getRecord();
const shouldBeValidFirst = returnedRecord[0][0] === 'child_0';
const isMissingOptionUndefined = returnedRecord[1];
return shouldBeValidFirst && isMissingOptionUndefined;
}
export function getRefTypeReturn(){
const getterFn = testModule.getFunction('getRefValue');
const classInstance = getterFn();
const canGetInterfaceMethod = Boolean(classInstance.getLiteral) && typeof classInstance.getLiteral === 'function'
const canGetNotDescribedMethod = Boolean(classInstance.methodNotDeclaredInInterface)
let failsOnInexistentMethod: boolean = false;
try {
classInstance.methodYouDontHave()
} catch {
failsOnInexistentMethod = true;
}
return canGetInterfaceMethod && canGetNotDescribedMethod && failsOnInexistentMethod;
}
export function getUnion(){
const getterFn = testModule.getFunction('getUnion');
// @ts-ignore
const instance = getterFn();
const foundResults: (number | boolean | string)[] = []
while (!foundResults.includes(1234) && !foundResults.includes(false) && !foundResults.includes('stringValue')) {
const runResult = instance.getUnion();
if (!foundResults.includes(runResult)) foundResults.push(runResult)
}
return true;
}

View File

@ -0,0 +1,54 @@
/**
* Copyright (c) 2024 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 <iostream>
#include <gtest/gtest.h>
#include "ets_interop_js_gtest.h"
namespace ark::ets::interop::js::testing {
class EtsInteropInterfaceReturnsValuesJsToArkts : public EtsInteropTest {};
/* test set employing interface imported from JS as is */
TEST_F(EtsInteropInterfaceReturnsValuesJsToArkts, test_interface_returns_literal_type_imported)
{
[[maybe_unused]] auto ret = CallJsMethod<bool>("getLiteralTypeReturn", "./index.js");
ASSERT_EQ(ret, true);
}
TEST_F(EtsInteropInterfaceReturnsValuesJsToArkts, test_interface_returns_native_array_type_imported)
{
[[maybe_unused]] auto ret = CallJsMethod<bool>("getNativeArrayReturn", "./index.js");
ASSERT_EQ(ret, true);
}
TEST_F(EtsInteropInterfaceReturnsValuesJsToArkts, DISABLED_test_interface_returns_record_type_imported)
{
[[maybe_unused]] auto ret = CallJsMethod<bool>("getRecordTypeReturn", "./index.js");
ASSERT_EQ(ret, true);
}
TEST_F(EtsInteropInterfaceReturnsValuesJsToArkts, test_interface_returns_ref_type_imported)
{
[[maybe_unused]] auto ret = CallJsMethod<bool>("getRefTypeReturn", "./index.js");
ASSERT_EQ(ret, true);
}
TEST_F(EtsInteropInterfaceReturnsValuesJsToArkts, test_interface_returns_union_type_imported)
{
[[maybe_unused]] auto ret = CallJsMethod<bool>("getUnion", "./index.js");
ASSERT_EQ(ret, true);
}
} // namespace ark::ets::interop::js::testing

View File

@ -0,0 +1,190 @@
/**
* Copyright (c) 2024 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.
*/
package interface_method_return_value
/**
* Interfaces for particular parameters
*/
interface IReturnLiteral{
getLiteral(): number
}
interface IReturnBoolean{
getBoolean(): boolean
}
interface IReturnArray{
getArray(): number[]
}
interface IReturnUnion {
getUnion(): int | boolean | string
}
interface ILiteralProperty{
someProp: number
}
interface IBooleanProperty{
booleanProperty: boolean
}
interface IMappedProperty{
mappedProperty: Record<number, string>
}
interface IReturnRecord {
getRecord(): Record<number, Record<number, string>>
}
/**
* Merged interface
*/
interface ISuperInterface extends IReturnLiteral,
IReturnArray,
IReturnBoolean,
ILiteralProperty,
IBooleanProperty,
IReturnRecord { };
function helperMakeNestedRecord(): Record<number, Record<number, string>> {
const childRef: Record<number, string> = { 0: "child_0", 1: "child_1", 100: "child_100"}
const parentRef: Record<number, Record<number, string>> = { 0: childRef }
return parentRef;
}
/**
* Interface implementations as separate classes to extend from
*/
class TestClass implements ISuperInterface {
literalProperty: number = 1234567980
someProp: number = 1234567980
booleanProperty: boolean = true
mappedProperty: Record<number, string> = { 1: 'one', 2: 'two', 3: 'three'}
nestedRecordProperty = helperMakeNestedRecord();
getLiteral(): number {
return 1234567890
}
getBoolean(): boolean {
return false;
}
getArray(): number[] {
const returnedArray: number[] = [1,2,3,4,5,6,8,9,0]
return returnedArray
}
loopback(): TestClass {
return this;
}
getRecord(): Record<number, Record<number, string>> {
const childRef: Record<number, string> = { 1: "child_1", 2: "child_2", 100: "child_100"}
const parentRef: Record<number, Record<number, string>> = { 0: childRef }
return parentRef;
}
methodNotDeclaredInInterface(){
return 'noninterface'
}
}
class ReturnsLiteral implements IReturnLiteral {
getLiteral(): number {
return 1234567890
}
}
class ReturnsBoolean implements IReturnBoolean {
getBoolean(): boolean {
return false;
}
}
class ReturnsUnion implements IReturnUnion {
getUnion(): boolean | int | string {
const seed = Math.random();
if (seed > 2/3) return 'stringValue';
return seed > 1/3 ? 1234 : true;
}
}
// class ReturnsRef implements IReturnRef {
// getNumber(): number {
// return 1234567890
// }
// getRef() {
// return this.getNumber
// }
// }
class ReturnsArray implements IReturnArray {
getArray(): number[] {
const returnedArray: number[] = [1,2,3,4,5,6,8,9,0]
return returnedArray
}
}
class HasLiteralProperty implements ILiteralProperty{
public someProp: number = 1234567980
}
class HasBooleanProperty implements IBooleanProperty{
booleanProperty: boolean = true
}
// class HasrefProperty implements IRefProperty{
// refProperty: Function<string>
// }
class HasMappedProperty implements IMappedProperty{
public mappedProperty: Record<number, string> = { 1: 'one', 2: 'two', 3: 'three'}
}
/**
* object getters
*/
class InstanceClass extends ReturnsArray implements IMappedProperty, ILiteralProperty {
mappedProperty: Record<number, string> = { 1: 'one', 2: 'two', 3: 'three'}
literalProperty: number = 123;
someProp: number = 123;
privProp(){
return 'prop'
}
}
function getBoolValue(): IReturnBoolean {
return new ReturnsBoolean()
}
function getArrayValue(): IReturnArray {
return new ReturnsArray()
}
function getRefValue(): ISuperInterface {
return new TestClass();
}
function getUnion(): IReturnUnion {
class UnionLocalClass extends ReturnsUnion implements IReturnUnion{
};
return (new UnionLocalClass())
}

View File

@ -0,0 +1,21 @@
# Copyright (c) 2024 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.
set(ETS_CONFIG ${CMAKE_CURRENT_BINARY_DIR}/arktsconfig.json)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/arktsconfig.in.json ${ETS_CONFIG})
panda_ets_interop_js_gtest(ets_interop_js_arkts_calls_js_interface_method__js_interfaces
CPP_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/test.cpp
ETS_SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/test.sts
ETS_CONFIG ${ETS_CONFIG}
)

View File

@ -0,0 +1,22 @@
{
"compilerOptions": {
"baseUrl": "${PANDA_ROOT}",
"paths": {
"escompat": ["${PANDA_ROOT}/plugins/ets/stdlib/escompat"],
"std": ["${PANDA_ROOT}/plugins/ets/stdlib/std"],
".": [
"${CMAKE_CURRENT_SOURCE_DIR}/index.js"]
},
"dynamicPaths": {
"${CMAKE_CURRENT_SOURCE_DIR}/index.js": {
"language": "js",
"hasDecl": false
},
"${CMAKE_CURRENT_SOURCE_DIR}/index.d.ts": {
"language": "js",
"hasDecl": true
}
}
}
}

View File

@ -0,0 +1,190 @@
/**
* Copyright (c) 2024 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.
*/
'use strict';
let __assign = (this && this.__assign) || function (...args) {
__assign = Object.assign || function(t) {
for (let s, i = 1, n = args.length; i < n; i++) {
s = args[i];
for (let p in s) {
if (Object.prototype.hasOwnProperty.call(s, p)) {
t[p] = s[p];
}
}
}
return t;
};
return __assign.apply(this, args);
};
let _a;
Object.defineProperty(exports, '__esModule', { value: true });
exports.testObject = exports.genericInterfaceImplementation = exports.GenericInterface = exports.ENUM_VALUE =
exports.UNDEFINED = exports.NULL_VALUE = exports.BOOLEAN_VALUE = exports.FLOAT_VALUE = exports.INT_VALUE =
exports.STRING_VALUE = void 0;
exports.STRING_VALUE = 'Panda';
exports.INT_VALUE = Number.MAX_SAFE_INTEGER;
exports.FLOAT_VALUE = Math.PI;
exports.BOOLEAN_VALUE = true;
exports.NULL_VALUE = null;
exports.UNDEFINED = (_a = {}) === null || _a === void 0 ? void 0 : _a.value;
let ENUM_VALUE;
(function (ENUM_VALUE) {
ENUM_VALUE[ENUM_VALUE.OPTION_ONE = 0] = 'OPTION_ONE';
ENUM_VALUE[ENUM_VALUE.OPTION_TWO = 1] = 'OPTION_TWO';
ENUM_VALUE[ENUM_VALUE.OPTION_THREE = 2] = 'OPTION_THREE';
})(ENUM_VALUE || (exports.ENUM_VALUE = ENUM_VALUE = {}));
let TUPLE_VALUE = ['abc', 123];
let genericInterface = /** @class */ (function () {
function genericInterface() {
this.getInt = function () {
return Number(exports.INT_VALUE);
};
this.getNegativeInt = function () {
return Number(exports.INT_VALUE) * -1;
};
this.getInfinity = function () {
return Number.POSITIVE_INFINITY;
};
this.getNegativeInfinity = function () {
return Number.NEGATIVE_INFINITY;
};
this.getNanAsNumber = function () {
return Number.NaN;
};
this.getBigInt = function () {
return BigInt(exports.INT_VALUE);
};
this.getFloat = function () {
return exports.FLOAT_VALUE;
};
this.getString = function () {
return exports.STRING_VALUE;
};
this.getBoolean = function () {
return exports.BOOLEAN_VALUE;
};
this.getEnum = function () {
return ENUM_VALUE;
};
this.getNull = function () {
return exports.NULL_VALUE;
};
this.getUndefined = function () {
return exports.UNDEFINED;
};
}
genericInterface.prototype.getAny = function () {
let randomValues = [exports.STRING_VALUE, exports.INT_VALUE, exports.FLOAT_VALUE, exports.BOOLEAN_VALUE,
exports.NULL_VALUE, exports.UNDEFINED, new Array(2).fill(' '), {}];
let index = Math.round(Math.random() * randomValues.length);
return randomValues[index];
};
genericInterface.prototype.getTuple = function () {
return ['tuple_item_0', 1];
};
genericInterface.prototype.getGeneric = function (arg) {
return __assign(__assign({}, arg), { extendingProperty: 0 });
};
genericInterface.prototype.getFunctionReturningType = function (arg) {
return function (arg) { return 0; };
};
return genericInterface;
}());
exports.GenericInterface = genericInterface;
exports.genericInterfaceImplementation = {
getAny: function () {
let randomValues = [
exports.STRING_VALUE,
exports.INT_VALUE,
exports.FLOAT_VALUE,
exports.BOOLEAN_VALUE,
exports.NULL_VALUE,
exports.UNDEFINED,
new Array(2).fill(' '),
{}
];
let index = Math.round(Math.random() * randomValues.length);
return randomValues[index];
},
getInt: function () {
return Number(exports.INT_VALUE);
},
getBigInt: function () {
return BigInt(exports.INT_VALUE);
},
getFloat: function () {
return exports.FLOAT_VALUE;
},
getNegativeInt: function () {
return Number(exports.INT_VALUE) * -1;
},
getInfinity: function () {
return Number.POSITIVE_INFINITY;
},
getNegativeInfinity: function () {
return Number.NEGATIVE_INFINITY;
},
getNanAsNumber: function () {
return Number.NaN;
},
getString: function () {
return exports.STRING_VALUE;
},
getBoolean: function () {
return exports.BOOLEAN_VALUE;
},
getTuple: function () {
return TUPLE_VALUE;
},
getGeneric: function (arg) {
return __assign(__assign({}, arg),
{ extendingProperty: Object.keys(arg !== null && arg !== void 0 ? arg : {}).length * -1 });
},
getFunctionReturningType: function (arg) {
return function () {
console.log('reached');
switch (typeof arg) {
case 'string':
return arg.toLowerCase() + arg.toUpperCase();
case 'bigint':
return arg / BigInt(2);
case 'number':
return arg * Math.PI;
default:
return 'undefined';
}
};
},
getEnum: function () {
return ENUM_VALUE;
},
getNull: function () {
return exports.NULL_VALUE;
},
getUndefined: function () {
return exports.UNDEFINED;
}
};
exports.testObject = {
a: 1
};

View File

@ -0,0 +1,214 @@
/**
* Copyright (c) 2024 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.
*/
export const STRING_VALUE = 'Panda';
export const INT_VALUE = Number.MAX_SAFE_INTEGER;
export const FLOAT_VALUE = Math.PI;
export const BOOLEAN_VALUE = true;
export const NULL_VALUE = null;
export const UNDEFINED = (<Record<string, undefined>>{})?.value;
export enum ENUM_VALUE {
OPTION_ONE,
OPTION_TWO,
OPTION_THREE
}
type TEST_TUPLE = [ string, number ]
const TUPLE_VALUE: TEST_TUPLE = ['abc', 123 ]
export interface AbstractInterface {
value: string
}
export interface ExtensionInterface {
extendingProperty: number
}
export type TFunctionReturnsType<T> = () => T
export type TFunctionReturnsAny = TFunctionReturnsType<any>
export type TFunctionReturnsString = TFunctionReturnsType<string>
export type TFunctionReturnsNumber = TFunctionReturnsType<number>
export type TFunctionReturnsBigInt = TFunctionReturnsType<bigint>
export type TFunctionReturnsBoolean = TFunctionReturnsType<boolean>
export type TFunctionReturnsStringLiteral = TFunctionReturnsType<"Panda">
export type TFunctionReturnsNumberLiteral = TFunctionReturnsType<1234>
export type TFunctionReturnsEnum = TFunctionReturnsType<typeof ENUM_VALUE>
export type TFunctionReturnsNull = TFunctionReturnsType<null>
export type TFunctionReturnsUndefined = TFunctionReturnsType<undefined>
export type TFunctionReturnsFunctionOfType<T> = (arg?: T) => TFunctionReturnsType<T>
export class GenericInterface {
getAny(): any {
const randomValues = [ STRING_VALUE, INT_VALUE, FLOAT_VALUE, BOOLEAN_VALUE, NULL_VALUE, UNDEFINED, new Array(2).fill(' '), <Record<string, any>>{}]
const index = Math.round(Math.random() * randomValues.length);
return randomValues[index];
}
public getInt: TFunctionReturnsNumber = function(){
return Number(INT_VALUE);
}
public getNegativeInt: TFunctionReturnsNumber = function(){
return Number(INT_VALUE)*-1;
}
public getInfinity: TFunctionReturnsNumber = function(){
return Number.POSITIVE_INFINITY;
}
public getNegativeInfinity: TFunctionReturnsNumber = function(){
return Number.NEGATIVE_INFINITY;
}
public getNanAsNumber: TFunctionReturnsNumber = function(){
return Number.NaN;
}
public getBigInt: TFunctionReturnsBigInt = function (){
return BigInt(INT_VALUE);
}
public getFloat: TFunctionReturnsNumber = function (){
return FLOAT_VALUE;
}
public getString: TFunctionReturnsString = function (){
return STRING_VALUE;
}
public getBoolean: TFunctionReturnsBoolean = function(){
return BOOLEAN_VALUE;
}
public getTuple(): TEST_TUPLE{
return [ 'tuple_item_0', 1 ]
}
public getGeneric<T extends {}>(arg: T): T & ExtensionInterface {
return { ...arg, extendingProperty: 0 }
}
public getFunctionReturningType<T>(arg?: T): () => T {
return (arg?: T) => 0 as T;
}
public getEnum: TFunctionReturnsEnum = function() {
return ENUM_VALUE
}
public getNull: TFunctionReturnsNull = function(){
return NULL_VALUE;
}
public getUndefined: TFunctionReturnsUndefined = function(){
return UNDEFINED;
}
}
export const genericInterfaceImplementation: GenericInterface = {
getAny(){
const randomValues = [
STRING_VALUE,
INT_VALUE,
FLOAT_VALUE,
BOOLEAN_VALUE,
NULL_VALUE,
UNDEFINED,
new Array(2).fill(' '),
<Record<string, any>>{}
];
const index = Math.round(Math.random() * randomValues.length);
return randomValues[index];
},
getInt(){
return Number(INT_VALUE);
},
getBigInt(){
return BigInt(INT_VALUE);
},
getFloat(){
return FLOAT_VALUE;
},
getNegativeInt(){
return Number(INT_VALUE)*-1;
},
getInfinity(){
return Number.POSITIVE_INFINITY;
},
getNegativeInfinity(){
return Number.NEGATIVE_INFINITY;
},
getNanAsNumber(){
return Number.NaN;
},
getString(){
return STRING_VALUE;
},
getBoolean(){
return BOOLEAN_VALUE;
},
getTuple() {
return TUPLE_VALUE;
},
getGeneric<T extends {}>(arg: T): T & ExtensionInterface {
return { ...arg, extendingProperty: Object.keys(arg ?? {}).length * -1 }
},
getFunctionReturningType<T>(arg?: T){
return () => {
console.log('reached')
switch (typeof arg) {
case 'string':
return (<string>arg).toLowerCase() + (<string>arg).toUpperCase() as T;
case 'bigint':
return (<bigint>arg) / BigInt(2) as T;
case 'number':
return (<number>arg) * Math.PI as T;
default:
return 'undefined' as T;
}
}
},
getEnum(){
return ENUM_VALUE
},
getNull(){
return NULL_VALUE;
},
getUndefined(){
return UNDEFINED;
}
};
export const testObject = {
a: 1
}

View File

@ -0,0 +1,103 @@
/**
* Copyright (c) 2024 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 <iostream>
#include <gtest/gtest.h>
#include "ets_interop_js_gtest.h"
namespace ark::ets::interop::js::testing {
class EtsInteropInterfaceReturnsValuesArkToJs : public EtsInteropTest {};
/* test set employing interface imported from JS as is */
TEST_F(EtsInteropInterfaceReturnsValuesArkToJs, test_interface_returns_any_type_imported)
{
[[maybe_unused]] auto ret = CallEtsMethod<bool>("type_imported__returnAny");
ASSERT_EQ(ret, true);
}
TEST_F(EtsInteropInterfaceReturnsValuesArkToJs, test_interface_returns_string_type_imported)
{
[[maybe_unused]] auto ret = CallEtsMethod<bool>("type_imported__returnString");
ASSERT_EQ(ret, true);
}
// NOTE 17741 -- disabled while JSValue BigInt is unsupported
TEST_F(EtsInteropInterfaceReturnsValuesArkToJs, DISABLED_test_interface_returns_bigint_type_imported)
{
[[maybe_unused]] auto ret = CallEtsMethod<bool>("type_imported__returnBigint");
ASSERT_EQ(ret, true);
}
TEST_F(EtsInteropInterfaceReturnsValuesArkToJs, test_interface_returns_boolean_type_imported)
{
[[maybe_unused]] auto ret = CallEtsMethod<bool>("type_imported__returnBoolean");
ASSERT_EQ(ret, true);
}
TEST_F(EtsInteropInterfaceReturnsValuesArkToJs, test_interface_returns_integer_type_imported)
{
[[maybe_unused]] auto ret = CallEtsMethod<bool>("type_imported__returnInteger");
ASSERT_EQ(ret, true);
}
TEST_F(EtsInteropInterfaceReturnsValuesArkToJs, test_interface_returns_negative_integer_type_imported)
{
[[maybe_unused]] auto ret = CallEtsMethod<bool>("type_imported__returnNegativeInteger");
ASSERT_EQ(ret, true);
}
TEST_F(EtsInteropInterfaceReturnsValuesArkToJs, test_interface_returns_infinity_type_imported)
{
[[maybe_unused]] auto ret = CallEtsMethod<bool>("type_imported__returnInfinity");
ASSERT_EQ(ret, true);
}
TEST_F(EtsInteropInterfaceReturnsValuesArkToJs, test_interface_returns_negative_infinity_type_imported)
{
[[maybe_unused]] auto ret = CallEtsMethod<bool>("type_imported__returnNegativeInfinity");
ASSERT_EQ(ret, true);
}
TEST_F(EtsInteropInterfaceReturnsValuesArkToJs, test_interface_returns_NaN_type_imported)
{
[[maybe_unused]] auto ret = CallEtsMethod<bool>("type_imported__returnNaN");
ASSERT_EQ(ret, true);
}
TEST_F(EtsInteropInterfaceReturnsValuesArkToJs, test_interface_returns_enum_type_imported)
{
[[maybe_unused]] auto ret = CallEtsMethod<bool>("type_imported__returnEnum");
ASSERT_EQ(ret, true);
}
TEST_F(EtsInteropInterfaceReturnsValuesArkToJs, test_interface_returns_undefined_type_imported)
{
[[maybe_unused]] auto ret = CallEtsMethod<bool>("type_imported__returnUndefined");
ASSERT_EQ(ret, true);
}
TEST_F(EtsInteropInterfaceReturnsValuesArkToJs, test_interface_returns_null_type_imported)
{
[[maybe_unused]] auto ret = CallEtsMethod<bool>("type_imported__returnNull");
ASSERT_EQ(ret, true);
}
TEST_F(EtsInteropInterfaceReturnsValuesArkToJs, test_interface_returns_function_type_imported)
{
[[maybe_unused]] auto ret = CallEtsMethod<bool>("type_imported__returnFunction");
ASSERT_EQ(ret, true);
}
} // namespace ark::ets::interop::js::testing

View File

@ -0,0 +1,142 @@
/**
* Copyright (c) 2024 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.
*/
import {
BOOLEAN_VALUE,
ENUM_VALUE,
GenericInterface,
STRING_VALUE,
TFunctionReturnsAny,
TFunctionReturnsBigInt,
TFunctionReturnsBoolean,
TFunctionReturnsEnum,
TFunctionReturnsFunctionOfType,
TFunctionReturnsNull,
TFunctionReturnsNumber,
TFunctionReturnsString,
TFunctionReturnsUndefined,
UNDEFINED,
genericInterfaceImplementation
} from ".";
/* Note: nullish \ undefish types here are workarounds for note 17745*/
type UndefishHelperType = undefined | string | number;
type NullishHelperType = null | string | number
function cleanup(): void {
try {
// trigger FinalizationRegistry cleanup
let full_gc_id = GC.startGC(GC.FULL_CAUSE);
GC.waitForFinishGC(full_gc_id);
} catch (e) {
assert false : "Unexpected exception during GC";
}
}
function type_imported__returnAny(){
const anyGetter: TFunctionReturnsAny = genericInterfaceImplementation.getAny as TFunctionReturnsAny;
return typeof anyGetter() == 'object';
}
function type_imported__returnString(){
const getterFn: TFunctionReturnsString = genericInterfaceImplementation.getString as TFunctionReturnsString;
return typeof getterFn() == "object" && (getterFn() as string == 'Panda')
}
function type_imported__returnBoolean(){
const getterFn: TFunctionReturnsBoolean = genericInterfaceImplementation.getBoolean;
return typeof getterFn() == "object" && (getterFn() as boolean) == true && (getterFn() as boolean) != false;
}
function type_imported__returnInteger(){
const getterFn: TFunctionReturnsNumber = genericInterfaceImplementation.getInt as TFunctionReturnsNumber;
return typeof getterFn() == "object" && (getterFn() as int) > 0 && (getterFn() as int) / 2 == (getterFn() as int) * 0.5;
}
function type_imported__returnNegativeInteger(){
const getterFn: TFunctionReturnsNumber = genericInterfaceImplementation.getNegativeInt;
return typeof getterFn() == "object" && (getterFn() as int) < 0 && (getterFn() as int) * -1 > 0;
}
function type_imported__returnInfinity(){
const getterFn: TFunctionReturnsNumber = genericInterfaceImplementation.getInfinity;
const isValid: boolean = (typeof getterFn() == "object")
&& ((getterFn() as number) > 0)
&& ((getterFn() as number) - 1 == getterFn())
&& !Number.isFinite(getterFn() as number);
cleanup();
return isValid;
}
function type_imported__returnNegativeInfinity(){
const getterFn: TFunctionReturnsNumber = genericInterfaceImplementation.getNegativeInfinity;
const isValid: boolean = (typeof getterFn() == "object")
&& ((getterFn() as number) < 0)
&& ((getterFn() as number) + 1 == getterFn())
&& !Number.isFinite(getterFn() as number);
cleanup();
return isValid;
}
function type_imported__returnNaN(){
const getterFn: TFunctionReturnsNumber = genericInterfaceImplementation.getNanAsNumber as TFunctionReturnsNumber;
const isValid: boolean = `${(getterFn() as number)}` == 'NaN' && (Number.isNaN(getterFn()));
cleanup();
return isValid;
}
function type_imported__returnBigint(){
const getterFn: TFunctionReturnsBigInt = genericInterfaceImplementation.getBigInt;
return typeof getterFn() == "object"
}
function type_imported__returnEnum(){
const getterFn: TFunctionReturnsEnum = genericInterfaceImplementation.getEnum;
const returnValue = getterFn();
const isAbleToGetExistingProperties = ((returnValue.OPTION_ONE as int == 0)
&& (returnValue.OPTION_TWO as number == 1)
&& (returnValue.OPTION_THREE as number == 2));
const isReturningUndefForMissingProperties = returnValue.OPTION_FOUR as UndefishHelperType == undefined;
cleanup();
return typeof getterFn() == "object" && isAbleToGetExistingProperties && isReturningUndefForMissingProperties
}
function type_imported__returnUndefined(){
const getterFn: TFunctionReturnsUndefined = genericInterfaceImplementation.getUndefined;
const returnValue = getterFn() as UndefishHelperType;
cleanup();
return returnValue == undefined && returnValue != '';
}
function type_imported__returnNull(){
const getterFn: TFunctionReturnsNull = genericInterfaceImplementation.getNull;
const returnValue = getterFn() as NullishHelperType;
return returnValue == null;
}
function type_imported__returnFunction(){
const getterFn: TFunctionReturnsFunctionOfType = genericInterfaceImplementation.getFunctionReturningType;
const returnStringValue = getterFn('panda');
const returnNumericValue = getterFn(1);
return returnStringValue() == 'pandaPANDA'
&& (returnNumericValue() as float)> 3
&& (returnNumericValue() as float) < 4;
}