Files
Hippy/tests/ios/HippyRootViewTest.mm
wwwcg c9ee0a92c2 feat(hermes): hermes engine support (phase I) (#4169)
* feat(hermes): support hermes engine first part

feat(hermes): support hermes engine second part

feat(hermes): close demo v8 serialization

feat(hermes): jsi mode support

feat(hermes): demo build script support hermes

feat(hermes): use std::any_cast in ios 11 when opening c++ exception

* fix(ios): resolve hermes build error

* feat(hermes): remove obsolete context wrapper

* feat(ios): support dynamic switching hermes and jsc

* feat(hermes): engine infrastructure improve

* feat(hermes): devtools support for ios

* feat(hermes): update engine version and

* feat(ios): drop v8 engine support

* refactor(ios): bridge setup process and update demo

chore(hermes): update hermes context imp

* chore(hermes): resolve build issue

* chore(ios): remove unnecessary assert

* fix(hermes): resolve context nullptr exception

* feat(hermes): using embeded hbc code for hermes

refactor native source code 's structure

* feat(hermes): resolve bugs and code clean

* feat(hermes): update ws url for devtools under hermes engine

use android as hermes's identity for now

* feat(hermes): resolve build issue

* feat(hermes): add ArrayBuffer type support

* fix(hermes): resolve rebase issues

code refactor for ios jeexecutor

* fix(hermes): dynamic load not support for hermes

Temporary solution

* chore(hermes): add warning ignore mark

* feat(hermes): engine ctx bugfix

* feat(hermes): resolve android build issues

* feat(hermes): resolve android build issue

* fix(hermes): add null pointer check during engine release

optimize call function imp

* feat(hermes): resolve context release issue

* feat(hermes): use toLocaleLowerCase since hermes support

* fix(hermes): resolve build issues

* feat(hermes): use toLowerCase in hippy js package

* chore(hermes): restore android demo params

* fix(core): adjust context destructor timing to avoid crash

* feat(hermes): resolve context bug and config update

* feat(hermes): update core build scripts for android and ohos

* feat(ios): update podspec and bump deployment version

* build(hermes): update build config for android and ohos

* feat(hermes): resolve ohos build issues

* fix(hermes): resolve ohos build issue

* fix(hermes): resolve test failure

* docs(hermes): add hermes usage guide

* chore(hermes): use jsc by default in demo

* feat(hermes): update docs and code optimize

* chore(ios): disable bitcode for iOS demo

* docs(hermes): update hermes usage guide

* chore(hermes): revert android config modify

* feat(hermes): context code optimization

* feat(hermes): context code optimization

* build(js): resolve some frontend build issues
2025-03-05 21:06:21 +08:00

200 lines
7.7 KiB
Plaintext

/*!
* iOS SDK
*
* Tencent is pleased to support the open source community by making
* Hippy available.
*
* Copyright (C) 2019 THL A29 Limited, a Tencent company.
* 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.
*/
#import <XCTest/XCTest.h>
#import <hippy/HippyView.h>
#import <hippy/HippyRootView.h>
#import <hippy/HippyUIManager.h>
#import <hippy/UIView+Hippy.h>
#import <hippy/UIView+Render.h>
#import "HippyComponentMap.h"
#import "HippyUIManager+Private.h"
#import "HippyJSEnginesMapper.h"
#import "NativeRenderManager.h"
#import "dom/root_node.h"
#import <OCMock/OCMock.h>
@interface UIView (HippyUIManagerUnitTest)
/// Bind UIView with HippyUIManager, for UnitTest
/// - Parameter uiManager: HippyUIManager instance
- (void)setUiManager:(HippyUIManager *)uiManager;
@end
@interface HippyRootContentView : HippyView
/// Init method
- (instancetype)initWithFrame:(CGRect)frame
bridge:(HippyBridge *)bridge
hippyTag:(NSNumber *)hippyTag
sizeFlexiblity:(HippyRootViewSizeFlexibility)sizeFlexibility;
#pragma mark - Snapshot
/// Retrieves the current snapshot data.
- (nullable NSData *)retrieveCurrentSnapshotData;
/// Restores the snapshot data with the provided NSData object.
/// - Parameter data: NSData object
- (BOOL)restoreSnapshotData:(nullable NSData *)data;
@end
@interface HippyRootView (UnitTest)
/// ContentView for HippyRootView
@property (nonatomic, strong) HippyRootContentView *contentView;
@end
/// Root tag for test
static NSNumber *const kHippyTestRootTag = @10;
@interface HippyRootViewTest : XCTestCase
/// Mock rootView
@property (nonatomic, strong) HippyRootView *mockRootView;
/// Mock HippyRootContentView
@property (nonatomic, strong) HippyRootContentView *mockContentView;
/// UIManager instance
@property (nonatomic, strong) HippyUIManager *uiManager;
@end
@implementation HippyRootViewTest
- (void)setUp {
[super setUp];
HippyBridge *bridge = [[HippyBridge alloc] initWithDelegate:nil moduleProvider:nil launchOptions:nil executorKey:nil];
HippyRootView *rootView = [[HippyRootView alloc] initWithBridge:bridge moduleName:@"Test" initialProperties:nil delegate:nil];
self.mockRootView = OCMPartialMock(rootView);
// Create ContentView's mock instance
HippyRootContentView *contentView = [[HippyRootContentView alloc] initWithFrame:CGRectZero
bridge:bridge
hippyTag:kHippyTestRootTag
sizeFlexiblity:HippyRootViewSizeFlexibilityNone];
self.mockContentView = OCMPartialMock(contentView);
OCMStub([self.mockRootView contentView]).andReturn(self.mockContentView);
// Create UIManager's instance
HippyUIManager *uiManager = [[HippyUIManager alloc] initWithBridge:bridge];
((HippyRootContentView *)self.mockContentView).uiManager = uiManager;
self.uiManager = uiManager;
}
- (void)tearDown {
[(id)self.mockContentView stopMocking];
[(id)self.mockRootView stopMocking];
[super tearDown];
}
- (void)testRetrieveCurrentSnapshotData_WhenRootNotNil {
// Set rootTag
OCMStub([self.mockContentView hippyTag]).andReturn(kHippyTestRootTag);
auto rootNode = std::make_shared<hippy::dom::RootNode>(kHippyTestRootTag.unsignedIntValue);
[self.mockContentView.uiManager.viewRegistry addRootComponent:self.mockRootView rootNode:rootNode forTag:kHippyTestRootTag];
// Retrive snapshot
NSData *result = [self.mockRootView retrieveCurrentSnapshotData];
OCMVerify([self.mockContentView retrieveCurrentSnapshotData]);
XCTAssertNotNil(result);
}
- (void)testRetrieveCurrentSnapshotData_WhenRootIsNil {
// Set test invalid rootTag @0
OCMStub([self.mockContentView hippyTag]).andReturn(@0);
auto rootNode = std::make_shared<hippy::dom::RootNode>(kHippyTestRootTag.unsignedIntValue);
[self.mockContentView.uiManager.viewRegistry addRootComponent:self.mockRootView rootNode:rootNode forTag:kHippyTestRootTag];
// Retrive snapshot
NSData *result = [self.mockRootView retrieveCurrentSnapshotData];
OCMVerify([self.mockContentView retrieveCurrentSnapshotData]);
XCTAssertNil(result);
}
- (void)testRestoreSnapshotData_WhenDataIsNil_ReturnsNO {
NSData *data = nil;
BOOL result = [self.mockRootView restoreSnapshotData:data];
OCMVerify([self.mockContentView restoreSnapshotData:[OCMArg any]]);
XCTAssertFalse(result);
}
- (void)testRestoreSnapshotData_WhenUIManagerIsNil_ReturnsNO {
self.mockContentView.uiManager = nil;
NSData *data = [NSData dataWithBytes:"mocked data" length:strlen("mocked data")];
BOOL result = [self.mockRootView restoreSnapshotData:data];
OCMVerify([self.mockContentView restoreSnapshotData:[OCMArg any]]);
XCTAssertFalse(result);
}
- (void)testRestoreSnapshotData_WhenRootNodeIsNil_ReturnsNO {
// Set invalid rootTag
OCMStub([self.mockContentView hippyTag]).andReturn(@0);
auto rootNode = std::make_shared<hippy::dom::RootNode>(kHippyTestRootTag.unsignedIntValue);
[self.mockContentView.uiManager.viewRegistry addRootComponent:self.mockRootView rootNode:rootNode forTag:kHippyTestRootTag];
// Set dom_manager
auto engineResource = [[HippyJSEnginesMapper defaultInstance] createJSEngineResourceForKey:@"testKey"
engineType:""
isDebug:NO];
auto domManager = engineResource->GetDomManager();
[self.mockContentView.uiManager setDomManager:domManager];
// Restore snapshot
NSData *data = [NSData dataWithBytes:"mocked data" length:strlen("mocked data")];
BOOL result = [self.mockRootView restoreSnapshotData:data];
OCMVerify([self.mockContentView restoreSnapshotData:[OCMArg any]]);
XCTAssertFalse(result);
}
- (void)testRestoreSnapshotData_WhenValidData_ReturnsYES {
// Set rootTag
OCMStub([self.mockContentView hippyTag]).andReturn(kHippyTestRootTag);
auto rootNode = std::make_shared<hippy::dom::RootNode>(kHippyTestRootTag.unsignedIntValue);
[self.mockContentView.uiManager.viewRegistry addRootComponent:self.mockRootView rootNode:rootNode forTag:kHippyTestRootTag];
// Retrive snapshot
NSData *snapshotData = [self.mockRootView retrieveCurrentSnapshotData];
OCMVerify([self.mockContentView retrieveCurrentSnapshotData]);
// Set dom_manager
auto engineResource = [[HippyJSEnginesMapper defaultInstance] createJSEngineResourceForKey:@"testKey"
engineType:""
isDebug:NO];
auto domManager = engineResource->GetDomManager();
[self.mockContentView.uiManager setDomManager:domManager];
auto nativeRenderManager = std::make_shared<NativeRenderManager>("testKey");
domManager->SetRenderManager(nativeRenderManager);
// Restore snapshot
BOOL result = [self.mockRootView restoreSnapshotData:snapshotData];
OCMVerify([self.mockContentView restoreSnapshotData:[OCMArg any]]);
XCTAssertTrue(result);
}
@end