@ohos-cpf/3rdloop 0.0.8 → 0.0.9
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +25 -0
- package/lib/cli.js +22 -5
- package/lib/doctor.js +111 -10
- package/lib/mcp.js +498 -0
- package/package.json +6 -2
- package/vendor/Archive/data/.index/meta.json +7 -0
- package/vendor/Archive/data/.index/search.db +0 -0
- package/vendor/Archive/data/docs/experiences/arkts-check-tool-pitfalls-baseline-comparison.md +13 -0
- package/vendor/Archive/data/docs/experiences/arkts-deep-path-import-recognition.md +31 -0
- package/vendor/Archive/data/docs/experiences/arkts-demo-coverage-entry-file-case-mismatch.md +25 -0
- package/vendor/Archive/data/docs/experiences/arkts-demo-coverage-import-trailing-slash.md +20 -0
- package/vendor/Archive/data/docs/experiences/arkts-library-source-files-may-be-ts.md +18 -0
- package/vendor/Archive/data/docs/experiences/arkts-typedarray-buffer-interface-cast-compile-fixes.md +36 -0
- package/vendor/Archive/data/docs/experiences/arkts-xts-compile-error-clustering-fix.md +24 -0
- package/vendor/Archive/data/docs/experiences/arkts-xts-doc-expected-value-runtime-probe.md +35 -0
- package/vendor/Archive/data/docs/experiences/arkts-xts-fixture-rawfile-testability-injection.md +33 -0
- package/vendor/Archive/data/docs/experiences/code-linter-chinese-comment-false-positive.md +16 -0
- package/vendor/Archive/data/docs/experiences/esobject-new-expression-variable-tracking.md +33 -0
- package/vendor/Archive/data/docs/experiences/filesystem-case-sensitivity-module-resolution.md +31 -0
- package/vendor/Archive/data/docs/experiences/gitcode-clone-redirect-warning-normal.md +13 -0
- package/vendor/Archive/data/docs/experiences/kn_msgvq1w585ec8319.md +77 -0
- package/vendor/Archive/data/docs/experiences/kn_msovnm6rd46de72c.md +98 -0
- package/vendor/Archive/data/docs/experiences/kn_mspt8vntfe708576.md +87 -0
- package/vendor/Archive/data/docs/experiences/kn_mspu1ei77adbbb48.md +133 -0
- package/vendor/Archive/data/docs/experiences/kn_mspubgak8d30bfce.md +128 -0
- package/vendor/Archive/data/docs/experiences/kn_mspug2de3cb1f7c3.md +115 -0
- package/vendor/Archive/data/docs/experiences/kn_skill_opt_001.md +38 -0
- package/vendor/Archive/data/docs/experiences/loop-artifacts-verification-evidence-triangle.md +19 -0
- package/vendor/Archive/data/docs/experiences/macos-bash-replace-build-ps1.md +19 -0
- package/vendor/Archive/data/docs/experiences/macos-bsd-diff-q-illegal-option.md +15 -0
- package/vendor/Archive/data/docs/experiences/migrate-cjs-compatible-api-version-map-limit.md +17 -0
- package/vendor/Archive/data/docs/experiences/mp3agic-arkts-library-behavior-quirks.md +21 -0
- package/vendor/Archive/data/docs/experiences/ohos-face-detection-scan-api-mapping.md +15 -0
- package/vendor/Archive/data/docs/experiences/pr-metadata-and-diff-integrity-verification.md +12 -0
- package/vendor/Archive/data/docs/experiences/rn-coverage-index-signature-pseudo-member-false-negative.md +32 -0
- package/vendor/Archive/data/docs/experiences/rn-memory-check-severity-calibration.md +21 -0
- package/vendor/Archive/data/docs/experiences/rn-platform-specific-api-exclusion-evidence.md +24 -0
- package/vendor/Archive/data/docs/experiences/rn-upstream-version-diff-pitfalls.md +17 -0
- package/vendor/Archive/data/docs/experiences/rn-version-gap-risk-rating-rules.md +13 -0
- package/vendor/Archive/data/docs/experiences/rn-view-lib-native-contract-diff-fabric-spec.md +16 -0
- package/vendor/Archive/data/docs/experiences/rnoh-adapter-package-version-field-semantics.md +18 -0
- package/vendor/Archive/data/docs/experiences/rnoh-arkts-sqlite-rows-array-format.md +18 -0
- package/vendor/Archive/data/docs/experiences/rnoh-dependency-residue-scan-strategy.md +18 -0
- package/vendor/Archive/data/docs/experiences/rnoh-example-local-lib-dep-use-tgz.md +53 -0
- package/vendor/Archive/data/docs/experiences/rnoh-example-prereserve-rntesterlist.md +17 -0
- package/vendor/Archive/data/docs/experiences/rnoh-example-template-compatiblesdkversion-upgrade.md +29 -0
- package/vendor/Archive/data/docs/experiences/rnoh-example-turbomodule-shell-adaptation-checklist.md +41 -0
- package/vendor/Archive/data/docs/experiences/rnoh-mcp-build-project-tool-risk.md +18 -0
- package/vendor/Archive/data/docs/experiences/rnoh-npm-devdependencies-version-precheck.md +29 -0
- package/vendor/Archive/data/docs/experiences/rnoh-repo-baseline-version-verification.md +13 -0
- package/vendor/Archive/data/docs/experiences/rnoh-repo-upstream-directory-mapping.md +18 -0
- package/vendor/Archive/data/docs/experiences/rnoh-stateless-library-zero-leak-verification.md +31 -0
- package/vendor/Archive/data/docs/experiences/rnoh-template-npmrc-credential-removal.md +15 -0
- package/vendor/Archive/data/docs/experiences/rnoh-turbomodule-codegen-wiring-verification.md +19 -0
- package/vendor/Archive/data/docs/experiences/rnoh-turbomodule-cpp-methodmap-compatibility-check.md +20 -0
- package/vendor/Archive/data/docs/experiences/scenario-doc-vs-source-signature-diff-four-patterns.md +24 -0
- package/vendor/Archive/data/docs/experiences/static-analysis-grep-cross-validation.md +29 -0
- package/vendor/Archive/demo.js +489 -0
- package/vendor/Archive/index.js +43 -0
- package/vendor/Archive/package.json +16 -0
- package/vendor/Archive/src/constants.js +83 -0
- package/vendor/Archive/src/data/stopwords.txt +110 -0
- package/vendor/Archive/src/data/synonyms.json +25 -0
- package/vendor/Archive/src/data/terms.txt +59 -0
- package/vendor/Archive/src/db/sqlite-backend.js +312 -0
- package/vendor/Archive/src/db/sqlite-schema.js +64 -0
- package/vendor/Archive/src/engine.js +501 -0
- package/vendor/Archive/src/index/index-manager.js +203 -0
- package/vendor/Archive/src/index/index-state.js +94 -0
- package/vendor/Archive/src/index/search-text-builder.js +106 -0
- package/vendor/Archive/src/index.js +22 -0
- package/vendor/Archive/src/parser/api-identifiers.js +121 -0
- package/vendor/Archive/src/parser/api-suffixes.js +48 -0
- package/vendor/Archive/src/parser/heading-normalize.js +40 -0
- package/vendor/Archive/src/parser/markdown-splitter.js +215 -0
- package/vendor/Archive/src/search/catalog-routing.js +87 -0
- package/vendor/Archive/src/search/fts-search.js +289 -0
- package/vendor/Archive/src/search/query-normalizer.js +159 -0
- package/vendor/Archive/src/search/query-rewriter.js +72 -0
- package/vendor/Archive/src/search/search-engine.js +72 -0
- package/vendor/Archive/src/search/snippet.js +64 -0
- package/vendor/Archive/src/store/dir-store.js +103 -0
- package/vendor/Archive/src/store/doc-store.js +36 -0
- package/vendor/Archive/src/tokenizer/lexicon.js +151 -0
- package/vendor/Archive/src/tokenizer/tokenizer.js +167 -0
- package/vendor/Archive/src/types.js +86 -0
- package/vendor/Archive/src/utils/hash.js +16 -0
- package/vendor/Archive/src/utils/lock.js +73 -0
- package/vendor/Archive/src/utils/path-safety.js +96 -0
- package/vendor/Archive/src/utils/paths.js +39 -0
- package/vendor/BadCase/rn/INDEX.md +127 -0
- package/vendor/BadCase/rn/cases/KI-001-webview/350/247/206/351/242/221/346/227/240/346/263/225/346/250/252/345/261/217.md +52 -0
- package/vendor/BadCase/rn/cases/KI-002-fastImage/347/203/255/346/233/264/346/226/260/345/233/276/347/211/207/345/244/261/350/264/245.md +37 -0
- package/vendor/BadCase/rn/cases/KI-003-wechat/347/274/251/347/225/245/345/233/276/346/234/254/345/234/260/345/233/276/347/211/207.md +62 -0
- package/vendor/BadCase/rn/cases/KI-004-wechat/345/233/236/350/260/203/346/227/266/345/272/217.md +47 -0
- package/vendor/BadCase/rn/cases/KI-005-geolocation/345/257/274/345/205/245/350/267/257/345/276/204/345/220/216/347/274/200.md +31 -0
- package/vendor/BadCase/rn/cases/KI-006-SmartRefreshLayout/346/231/272/350/203/275/346/214/207/351/222/210/345/264/251/346/272/203.md +55 -0
- package/vendor/BadCase/rn/cases/KI-007-orientation-locker/344/274/240/346/204/237/345/231/250/345/210/235/345/247/213/345/214/226.md +58 -0
- package/vendor/BadCase/rn/cases/KI-008-orientation-locker/344/274/240/346/204/237/345/231/250/345/274/225/347/224/250/350/256/241/346/225/260.md +47 -0
- package/vendor/BadCase/rn/cases/KI-009-pager-view/345/265/214/345/245/227/346/273/221/345/212/250.md +38 -0
- package/vendor/BadCase/rn/cases/KI-010-screens/346/211/213/345/212/277/345/206/262/347/252/201.md +48 -0
- package/vendor/BadCase/rn/cases/KI-011-spring-scrollview/346/211/213/345/212/277/351/207/215/345/244/215/347/273/221/345/256/232.md +49 -0
- package/vendor/BadCase/rn/cases/KI-012-qr-camera/346/250/252/345/261/217/351/200/202/351/205/215.md +59 -0
- package/vendor/BadCase/rn/cases/KI-013-webview/346/267/261/350/211/262/346/250/241/345/274/217/350/203/214/346/231/257/350/211/262.md +37 -0
- package/vendor/BadCase/rn/cases/KI-014-amap-geolocation/345/233/236/350/260/203/347/274/272/345/244/261.md +42 -0
- package/vendor/BadCase/rn/cases/KI-015-reanimated/350/277/220/350/241/214/346/227/266/346/236/220/346/236/204/345/264/251/346/272/203.md +54 -0
- package/vendor/BadCase/rn/cases/KI-016-fs/346/226/207/344/273/266/350/257/273/345/217/226/347/274/226/347/240/201.md +58 -0
- package/vendor/BadCase/rn/cases/KI-017-blob-util/345/217/202/346/225/260/347/274/226/347/240/201/351/224/231/350/257/257.md +39 -0
- package/vendor/BadCase/rn/cases/KI-018-modal/345/274/271/347/252/227/351/227/252/347/203/201.md +53 -0
- package/vendor/BadCase/rn/cases/KI-019-code-push/351/207/215/345/220/257/351/200/273/350/276/221/345/244/261/346/225/210.md +79 -0
- package/vendor/BadCase/rn/cases/KI-020-netinfo/346/225/217/346/204/237/344/277/241/346/201/257/346/263/204/351/234/262.md +60 -0
- package/vendor/BadCase/rn/cases/KI-021-video/346/234/254/345/234/260/350/247/206/351/242/221/346/222/255/346/224/276/345/274/202/345/270/270.md +79 -0
- package/vendor/BadCase/rn/cases/KI-022-audio-recorder-player/346/236/232/344/270/276/347/274/272/345/244/261.md +38 -0
- package/vendor/BadCase/rn/cases/KI-023-svg/346/270/220/345/217/230/347/273/247/346/211/277/345/244/261/346/225/210.md +62 -0
- package/vendor/BadCase/rn/generalization-log.md +55 -0
- package/vendor/BadCase/rn/pr-info/rntpc_react-native-SmartRefreshLayout-32.json +328 -0
- package/vendor/BadCase/rn/pr-info/rntpc_react-native-SmartRefreshLayout-32.md +382 -0
- package/vendor/BadCase/rn/pr-info/rntpc_react-native-amap-geolocation-27.json +1351 -0
- package/vendor/BadCase/rn/pr-info/rntpc_react-native-amap-geolocation-27.md +1176 -0
- package/vendor/BadCase/rn/pr-info/rntpc_react-native-audio-recorder-player-22.json +538 -0
- package/vendor/BadCase/rn/pr-info/rntpc_react-native-audio-recorder-player-22.md +1488 -0
- package/vendor/BadCase/rn/pr-info/rntpc_react-native-blob-util-23.json +211 -0
- package/vendor/BadCase/rn/pr-info/rntpc_react-native-blob-util-23.md +35 -0
- package/vendor/BadCase/rn/pr-info/rntpc_react-native-code-push-17.json +2048 -0
- package/vendor/BadCase/rn/pr-info/rntpc_react-native-code-push-17.md +3866 -0
- package/vendor/BadCase/rn/pr-info/rntpc_react-native-fast-image-102.json +198 -0
- package/vendor/BadCase/rn/pr-info/rntpc_react-native-fast-image-102.md +40 -0
- package/vendor/BadCase/rn/pr-info/rntpc_react-native-fs-38.json +751 -0
- package/vendor/BadCase/rn/pr-info/rntpc_react-native-fs-38.md +883 -0
- package/vendor/BadCase/rn/pr-info/rntpc_react-native-geolocation-24.json +1544 -0
- package/vendor/BadCase/rn/pr-info/rntpc_react-native-geolocation-24.md +2598 -0
- package/vendor/BadCase/rn/pr-info/rntpc_react-native-modal-20.json +246 -0
- package/vendor/BadCase/rn/pr-info/rntpc_react-native-modal-20.md +554 -0
- package/vendor/BadCase/rn/pr-info/rntpc_react-native-netinfo-31.json +211 -0
- package/vendor/BadCase/rn/pr-info/rntpc_react-native-netinfo-31.md +54 -0
- package/vendor/BadCase/rn/pr-info/rntpc_react-native-orientation-locker-45.json +1626 -0
- package/vendor/BadCase/rn/pr-info/rntpc_react-native-orientation-locker-45.md +2213 -0
- package/vendor/BadCase/rn/pr-info/rntpc_react-native-orientation-locker-51.json +208 -0
- package/vendor/BadCase/rn/pr-info/rntpc_react-native-orientation-locker-51.md +77 -0
- package/vendor/BadCase/rn/pr-info/rntpc_react-native-pager-view-32.json +377 -0
- package/vendor/BadCase/rn/pr-info/rntpc_react-native-pager-view-32.md +174 -0
- package/vendor/BadCase/rn/pr-info/rntpc_react-native-qr-decode-image-camera-37.json +232 -0
- package/vendor/BadCase/rn/pr-info/rntpc_react-native-qr-decode-image-camera-37.md +194 -0
- package/vendor/BadCase/rn/pr-info/rntpc_react-native-reanimated-82.json +198 -0
- package/vendor/BadCase/rn/pr-info/rntpc_react-native-reanimated-82.md +67 -0
- package/vendor/BadCase/rn/pr-info/rntpc_react-native-screens-87.json +198 -0
- package/vendor/BadCase/rn/pr-info/rntpc_react-native-screens-87.md +38 -0
- package/vendor/BadCase/rn/pr-info/rntpc_react-native-screens-93.json +208 -0
- package/vendor/BadCase/rn/pr-info/rntpc_react-native-screens-93.md +34 -0
- package/vendor/BadCase/rn/pr-info/rntpc_react-native-spring-scrollview-38.json +222 -0
- package/vendor/BadCase/rn/pr-info/rntpc_react-native-spring-scrollview-38.md +56 -0
- package/vendor/BadCase/rn/pr-info/rntpc_react-native-svg-117.json +463 -0
- package/vendor/BadCase/rn/pr-info/rntpc_react-native-svg-117.md +383 -0
- package/vendor/BadCase/rn/pr-info/rntpc_react-native-video-66.json +464 -0
- package/vendor/BadCase/rn/pr-info/rntpc_react-native-video-66.md +565 -0
- package/vendor/BadCase/rn/pr-info/rntpc_react-native-webview-112.json +198 -0
- package/vendor/BadCase/rn/pr-info/rntpc_react-native-webview-112.md +47 -0
- package/vendor/BadCase/rn/pr-info/rntpc_react-native-webview-121.json +232 -0
- package/vendor/BadCase/rn/pr-info/rntpc_react-native-webview-121.md +422 -0
- package/vendor/BadCase/rn/pr-info/rntpc_react-native-wechat-lib-15.json +295 -0
- package/vendor/BadCase/rn/pr-info/rntpc_react-native-wechat-lib-15.md +1038 -0
- package/vendor/BadCase/rn/rules/R-01-/345/205/250/345/261/217/347/252/227/345/217/243/347/212/266/346/200/201/347/256/241/347/220/206/345/256/214/346/225/264/346/200/247.md +20 -0
- package/vendor/BadCase/rn/rules/R-02-/350/265/204/346/272/220URI/345/275/242/346/200/201/345/210/206/346/224/257/350/246/206/347/233/226.md +21 -0
- package/vendor/BadCase/rn/rules/R-03-/351/231/204/345/261/236/346/223/215/344/275/234/345/244/261/350/264/245/351/230/273/346/226/255/344/270/273/346/265/201/347/250/213.md +20 -0
- package/vendor/BadCase/rn/rules/R-04-/345/274/202/346/255/245/345/233/236/350/260/203/346/263/250/345/206/214/346/227/266/345/272/217.md +20 -0
- package/vendor/BadCase/rn/rules/R-05-/346/250/241/345/235/227/345/257/274/345/205/245/350/267/257/345/276/204/350/247/204/350/214/203.md +19 -0
- package/vendor/BadCase/rn/rules/R-06-/344/274/240/346/204/237/345/231/250/347/241/254/344/273/266/346/235/203/351/231/220/346/214/211/351/234/200/350/216/267/345/217/226.md +21 -0
- package/vendor/BadCase/rn/rules/R-07-/346/231/272/350/203/275/346/214/207/351/222/210/347/224/237/345/221/275/345/221/250/346/234/237/347/256/241/347/220/206.md +20 -0
- package/vendor/BadCase/rn/rules/R-08-/346/211/213/345/212/277/344/272/213/344/273/266/346/263/250/345/206/214/344/270/216/345/206/262/347/252/201/345/244/204/347/220/206.md +22 -0
- package/vendor/BadCase/rn/rules/R-09-/346/250/252/347/253/226/345/261/217/345/244/232/345/275/242/346/200/201/345/270/203/345/261/200/351/200/202/351/205/215.md +20 -0
- package/vendor/BadCase/rn/rules/R-10-/346/267/261/350/211/262/346/250/241/345/274/217/344/270/273/351/242/230/351/242/234/350/211/262/351/200/202/351/205/215.md +19 -0
- package/vendor/BadCase/rn/rules/R-11-/346/216/245/345/217/243/345/233/236/350/260/203/345/256/236/347/216/260/345/256/214/346/225/264/346/200/247.md +20 -0
- package/vendor/BadCase/rn/rules/R-12-/345/216/237/347/224/237/350/277/220/350/241/214/346/227/266/350/265/204/346/272/220/346/236/220/346/236/204/346/227/266/345/272/217.md +20 -0
- package/vendor/BadCase/rn/rules/R-13-/346/226/207/344/273/266/346/225/260/346/215/256/347/274/226/347/240/201/344/270/216/346/240/274/345/274/217/345/205/274/345/256/271.md +21 -0
- package/vendor/BadCase/rn/rules/R-14-/345/212/250/347/224/273/345/210/235/345/247/213/345/214/226/346/227/266/345/272/217/344/270/216/347/212/266/346/200/201/345/220/214/346/255/245.md +20 -0
- package/vendor/BadCase/rn/rules/R-15-/347/212/266/346/200/201/346/214/201/344/271/205/345/214/226/344/270/216/351/207/215/345/220/257/351/200/273/350/276/221/344/270/200/350/207/264/346/200/247.md +20 -0
- package/vendor/BadCase/rn/rules/R-16-/346/225/217/346/204/237/344/277/241/346/201/257/346/227/245/345/277/227/346/263/204/351/234/262.md +19 -0
- package/vendor/BadCase/rn/rules/R-17-/345/252/222/344/275/223/350/265/204/346/272/220/347/224/237/345/221/275/345/221/250/346/234/237/344/270/216/351/224/231/350/257/257/345/244/204/347/220/206.md +21 -0
- package/vendor/BadCase/rn/rules/R-18-/350/203/275/345/212/233/346/236/232/344/270/276/351/205/215/347/275/256/345/256/214/346/225/264/346/200/247.md +19 -0
- package/vendor/BadCase/rn/rules/R-19-/345/233/276/345/275/242/346/270/262/346/237/223/345/261/236/346/200/247/347/273/247/346/211/277/344/270/216/351/207/215/347/275/256.md +19 -0
- package/vendor/MCP/README.md +490 -0
- package/vendor/MCP/config.json +29 -0
- package/vendor/MCP/package.json +23 -0
- package/vendor/MCP/scripts/analyze-demo-coverage.cjs +1203 -0
- package/vendor/MCP/scripts/analyze-xts-coverage.cjs +1245 -0
- package/vendor/MCP/scripts/deveco_docs.js +247 -0
- package/vendor/MCP/scripts/extract-interfaces.cjs +1487 -0
- package/vendor/MCP/scripts/flutter-analyze-demo-coverage.cjs +666 -0
- package/vendor/MCP/scripts/flutter-analyze-xts-coverage.cjs +684 -0
- package/vendor/MCP/scripts/flutter-extract-interfaces.cjs +1251 -0
- package/vendor/MCP/scripts/flutter-render-spec-doc.cjs +351 -0
- package/vendor/MCP/scripts/render-spec-doc.cjs +347 -0
- package/vendor/MCP/scripts/rn-analyze-demo-coverage.cjs +645 -0
- package/vendor/MCP/scripts/rn-analyze-test-coverage.cjs +614 -0
- package/vendor/MCP/scripts/rn-extract-interfaces.cjs +1462 -0
- package/vendor/MCP/scripts/rn-render-spec-doc.cjs +327 -0
- package/vendor/MCP/scripts/rn-scan-exports.cjs +1336 -0
- package/vendor/MCP/src/client/MCPClientPool.js +220 -0
- package/vendor/MCP/src/config/ConfigLoader.js +189 -0
- package/vendor/MCP/src/executor/ScriptExecutor.js +110 -0
- package/vendor/MCP/src/gateway/Gateway.js +451 -0
- package/vendor/MCP/src/index.js +87 -0
- package/vendor/MCP/src/library/KBToolProvider.js +229 -0
- package/vendor/MCP/src/library/logger.js +60 -0
- package/vendor/MCP/src/registry/ScriptRegistry.js +238 -0
- package/vendor/MCP/src/registry/ToolRegistry.js +111 -0
- package/vendor/MCP/src/types.js +115 -0
- package/vendor/Server/Skills/arkts-library-test-coverage-check/references/MCP_TOOL_USAGE.md +4 -2
- package/vendor/Server/Skills/arkts-library-xts-coverage/SKILL.md +3 -3
- package/vendor/Server/Skills/knowledge-import/SKILL.md +1 -1
- package/vendor/Server/Skills/knowledge-import/references/MCP_TOOL_USAGE.md +12 -4
- package/vendor/Server/Skills/ohos-lib-pr-push/SKILL.md +5 -4
- package/vendor/Server/Skills/rn-library-issue-generalizer/SKILL.md +2 -2
- package/vendor/Server/Skills/rn-library-known-issue-check/SKILL.md +2 -2
- package/vendor/Server/Skills/rnoh-lib-demo-coverage/SKILL.md +1 -2
- package/vendor/Server/Skills/rnoh-lib-test-align/references/port-test-demo-guide.md +1 -1
- package/vendor/Server/Skills/rnoh-lib-xts-coverage/SKILL.md +1 -2
- package/vendor/Server/package.json +5 -1
- package/vendor/VERSION +3 -3
package/vendor/Archive/data/docs/experiences/arkts-typedarray-buffer-interface-cast-compile-fixes.md
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
## ArkTS 严格模式两类高频编译错误修复模板(TypedArray.buffer / 接口强转实现类)
|
|
2
|
+
|
|
3
|
+
### 问题现象
|
|
4
|
+
|
|
5
|
+
ArkTS 严格模式下生成 Demo 代码时两类高频编译错误(mp3agic Demo 生成中 5 个编译错误全部属于这两类):
|
|
6
|
+
|
|
7
|
+
1. `arkts-no-structural-typing`:将 `new Uint8Array([1, 2]).buffer` 赋值给 `ArrayBuffer` 类型变量报错。根因:`.buffer` 属性类型为 `ArrayBufferLike`,属结构化类型,严格模式禁止此类赋值。
|
|
8
|
+
2. `neither type sufficiently overlaps`:接口类型向实现类 `as` 强转报错(如 `ID3v2` → `ID3v23Tag`、`ID3v2Frame` → `ID3v2ObseleteFrame`)。根因:接口声明与类成员不重叠时,TS 认为两类型不重叠,直接强转非法。
|
|
9
|
+
|
|
10
|
+
### 解决方案
|
|
11
|
+
|
|
12
|
+
**模板 1:TypedArray → ArrayBuffer 安全构造**
|
|
13
|
+
|
|
14
|
+
```typescript
|
|
15
|
+
// ❌ const buf: ArrayBuffer = new Uint8Array([1, 2]).buffer; // arkts-no-structural-typing
|
|
16
|
+
// ✅
|
|
17
|
+
const buf: ArrayBuffer = new ArrayBuffer(2);
|
|
18
|
+
const view: Uint8Array = new Uint8Array(buf);
|
|
19
|
+
view[0] = 1; view[1] = 2;
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
**模板 2:接口 → 实现类安全转型(替代 as 强转)**
|
|
23
|
+
|
|
24
|
+
```typescript
|
|
25
|
+
// ❌ const tag: ID3v23Tag = mp3.getId3v2Tag() as ID3v23Tag;
|
|
26
|
+
// ✅
|
|
27
|
+
const raw: ID3v2 = mp3.getId3v2Tag();
|
|
28
|
+
if (!(raw instanceof ID3v23Tag)) { /* 错误处理 */ return; }
|
|
29
|
+
const tag: ID3v23Tag = raw;
|
|
30
|
+
```
|
|
31
|
+
|
|
32
|
+
**注意**:instanceof 收窄修复会引入新的类型引用,必须同步补全对应 import 语句,否则下一轮编译报 `Cannot find name 'X'`。
|
|
33
|
+
|
|
34
|
+
### 结果
|
|
35
|
+
|
|
36
|
+
两类写法各消耗一轮编译循环后方才修复;后续遇到同类问题直接套用模板可各避免一轮编译循环。修复引入新类型时同步检查 import 可再省一轮。
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
## ArkTS XTS 测试编译错误按根因聚类批量修复(含接口/实现类型不匹配等典型模式)
|
|
2
|
+
|
|
3
|
+
### 问题现象
|
|
4
|
+
mp3agic XTS 测试首轮编译出现 86 个错误。其中存在一类隐蔽的编译阻断:库接口声明的方法返回类型为 `Array<>` 而实现类实际返回 `JList<>`,导致**实现类实例无法赋值给接口类型参数**(如 `setId3v2Tag(v2Tag)`、`getId3v2Tag() === v2Tag`),测试代码中所有"实现类实例 → 接口参数/比较"路径全部编译失败。该类缺陷在 Demo 中不暴露(Demo 从不把具体实现类传给接受接口的方法),只有测试代码首次触达该赋值路径时才显现——**接口签名与实现返回类型不匹配是三方库测试代码的典型编译阻断源**。
|
|
5
|
+
|
|
6
|
+
### 解决方案
|
|
7
|
+
**按错误根因聚类批量修复**,而非逐条修。mp3agic 86 错误的根因只有 4 类,1 轮清零:
|
|
8
|
+
- 75 × 裸断言 → 括号配平转换器脚本批量转换(1 次)
|
|
9
|
+
- 4 × 重复 import → 去重(1 次)
|
|
10
|
+
- 1 × null 实参 → 等价 falsy 值替换(1 次)
|
|
11
|
+
- 6 × 接口/实现类型不匹配 → 修库接口声明(1 处修复消全部)
|
|
12
|
+
|
|
13
|
+
**典型错误模式识别表**:
|
|
14
|
+
|
|
15
|
+
1. **接口/实现返回类型不匹配**:`Argument of type 'ID3v23Tag' is not assignable to parameter of type 'ID3v2'. The types returned by 'getChapters()' are incompatible` + `is missing the following properties from type` → 库接口方法返回类型声明与实现类不一致。修复方式:**修接口声明对齐实现**(如 `Array<>` 改 `JList<>`),而非在测试里强转绕过。属源库机械性修正。
|
|
16
|
+
|
|
17
|
+
2. **裸断言调用**:subagent 生成 `assertTrue(x)` / `assertEqual(a, b)` 裸函数调用而非 `expect(x).assertTrue()` 链式调用 → 批量 "Cannot find name 'assertTrue'" 错误。修复:编写括号配平转换器(解析顶层逗号切分双参断言、单参断言直接包裹)一次性转换。预防:生成 prompt 中给出断言正反例,明确 `assertTrue(x)` 裸调用是错误写法。
|
|
18
|
+
|
|
19
|
+
3. **ArkTS 严格空值检查拒收 null 实参**:`new ID3v1Tag(null)` 报 `Argument of type 'null' is not assignable to parameter of type 'string'`。库源码虽有 `@ts-nocheck`,但**测试文件调用库 API 时仍受严格检查约束**。修复:库构造函数用 `if (data)` 判空(空串与 null 语义等价)时,改用 `new ID3v1Tag('')` 覆盖同一路径,需在注释中说明等价性依据。
|
|
20
|
+
|
|
21
|
+
4. **未从根入口导出的类型需深层路径导入**:实现类(如 ID3v1Tag)与自定义异常类(NoSuchTagException 等)未在 `library/index.ets` 导出,测试需深层路径导入:`import { ID3v1Tag } from '@ohos/mp3agic/src/main/ets/components/mp3agic/ID3v1Tag'`。**异常类必须真实 import 后才能用 `e instanceof XxxException` 做类型断言**。
|
|
22
|
+
|
|
23
|
+
### 结果
|
|
24
|
+
86 个编译错误 1 轮修复后 clean 全量重建 BUILD SUCCESSFUL(Code Linter 0 Error)。根因聚类修复(4 类各修 1 次)远快于逐条修 86 次。同类错误重复出现在多个文件时,优先写一次性批量转换脚本而非逐文件手改。
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
## ArkTS 三方库 XTS 测试:用例文档预期值不可盲信,生成前用 Node 运行时探针实测锁定
|
|
2
|
+
|
|
3
|
+
### 问题现象
|
|
4
|
+
基于 XTS 用例描述文档直接生成断言代码时,文档中的预期结果大量来自对上游原版库(如 Java 版)行为的语义推断,与 ArkTS 移植版实际运行行为存在系统性偏差。mp3agic 案例实测:47 个用例中至少 8 处预期值错误,按文档值直接生成断言必然运行时失败。典型偏差类型:
|
|
5
|
+
|
|
6
|
+
- **返回类型偏差**:文档预期 `getTrack()` 返回 string `'5'`,实际返回 number `5`(unpackTag 直接存 charCode,未转 string)
|
|
7
|
+
- **越界访问偏差**:文档预期越界流派描述返回 `'Unknown'`,实际返回 `undefined`(数组负索引访问不抛异常,catch 回退分支不可达)
|
|
8
|
+
- **空值返回偏差**:文档预期空标签 `getChapters()` 返回空列表,实际返回 `null`(frameSet 为 null 时直接 return null)
|
|
9
|
+
- **默认值偏差**:文档预期新标签 `getPadding()` 默认 `true`,实际默认 `false`(字段声明 `protected padding: boolean = false`)
|
|
10
|
+
- **异常行为偏差**:文档预期非法编码编号的 `toBytes` 抛 IllegalArgumentException,实际不抛异常返回普通文本字节(`characterSets[9]` 越界取 undefined 而非抛异常)
|
|
11
|
+
- **构造参数语义偏差**:`new ID3v2PopmFrameData(false, null, 0)` 的空地址路径与文档描述不符(rating 非 null 时构造函数自动写入默认地址)
|
|
12
|
+
|
|
13
|
+
### 解决方案
|
|
14
|
+
**模式:生成前运行时探针锁定期望值**
|
|
15
|
+
|
|
16
|
+
```
|
|
17
|
+
流程:解析用例文档 → 提取全部断言点 → Node 探针直跑库源码逐条实测
|
|
18
|
+
→ 实测值回填生成 prompt → 按实测值生成代码 → 编译验证
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
**适用条件**:库源码为纯 TS/ETS 且平台依赖可桩化(`@ohos.hilog` 可空桩、`@ohos.buffer`/`@ohos.fileio` 可替换)。mp3agic 类库(源码全 `.ts`、平台依赖仅日志/缓冲/文件 IO)完全满足。
|
|
22
|
+
|
|
23
|
+
**Node 探针环境改造清单**(对库源码副本操作,约 30 分钟):
|
|
24
|
+
1. 桩模块:`@ohos.hilog`(空实现)、`@ohos.buffer`、`@ohos.fileio`。⚠️ fileio flag 语义映射:鸿蒙 `0o102` = O_RDWR|O_CREAT|O_TRUNC,且库传的是数字不是字符串
|
|
25
|
+
2. import 路径补 `.ts` 扩展名(Node ESM 解析要求):`perl -i -pe 's|from "(\./[A-Za-z0-9]+)"|from "./$1.ts"|g'`
|
|
26
|
+
3. ArkTS 专有语法降级:`static const` → `static`
|
|
27
|
+
4. 仅类型导入修正:接口文件改 `import type`,否则报 "does not provide an export named"
|
|
28
|
+
5. ⚠️ 探针特有陷阱:Node class-fields 语义下子类字段声明会覆盖父类构造函数赋值(如 `private path: string` 声明清空 `super(path)` 的赋值),需在探针副本中注释掉该声明。该问题仅存在于探针环境,ArkTS 编译器不产生此语义,勿"修复"真实源码
|
|
29
|
+
|
|
30
|
+
运行方式:Node 24+ `node --experimental-strip-types probe.mjs`,配合工程内真实样本夹具可覆盖从标签解析、字节序列化到 save 文件回读的全部断言路径。
|
|
31
|
+
|
|
32
|
+
**补充(真机签名阻断的替代验证)**:真机要求签名 HAP,本机可能无目标包名的调试 Profile(CLI 无法代签)。此时探针可作为替代验证手段完成全部用例期望值的运行时验证(含异常类型/消息、字节布局、保存回读闭环),报告中如实标注"未真机执行 + 原因 + 替代验证手段"。
|
|
33
|
+
|
|
34
|
+
### 结果
|
|
35
|
+
mp3agic 案例中,8 处文档偏差、5 处库源码缺陷全部在写代码前发现,47/47 用例断言值与库实际行为吻合,编译后零运行时断言返工。成本约 30 分钟环境搭建 + 15 分钟探针编写,收益远超成本。**结论:文档预期值不可盲信,必须实测;实测与文档不符时以实测为准并在代码注释标注偏差。**
|
package/vendor/Archive/data/docs/experiences/arkts-xts-fixture-rawfile-testability-injection.md
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
## XTS 测试夹具零依赖交付:rawfile 内置 + TestAbility 注入(替代 hdc file send 的首选方案)
|
|
2
|
+
|
|
3
|
+
### 问题现象
|
|
4
|
+
XTS 测试需要 MP3/ID3 样本文件等二进制夹具。传统方案依赖 `hdc file send` 手工推送文件到设备(需连接设备、逐个手工操作、CI 无法自动复跑)或外部网络下载(环境不可控、违反离线约束)。
|
|
5
|
+
|
|
6
|
+
### 解决方案
|
|
7
|
+
**夹具 rawfile 内置 + TestAbility 注入模式**(零网络、零手工设备操作):
|
|
8
|
+
|
|
9
|
+
1. 夹具文件放置 `entry/src/ohosTest/resources/rawfile/`(随 ohosTest HAP 自动打包,已验证 unzip HAP 可见 `resources/rawfile/`)
|
|
10
|
+
2. 在 TestAbility.onCreate 中、`Hypium.hypiumTest` 调用之前,将 rawfile 夹具释放到应用沙箱目录:
|
|
11
|
+
|
|
12
|
+
```typescript
|
|
13
|
+
private prepareMp3Fixtures(): void {
|
|
14
|
+
const fixtureFiles: string[] = ['notags.mp3', 'v1andv24tags.mp3', /* ... */];
|
|
15
|
+
const filesDir: string = this.context.filesDir;
|
|
16
|
+
GlobalContext.getContext().setValue('path', filesDir); // 若库通过 GlobalContext 读取工作目录(如 save() 依赖 'path' 键),必须在此设置
|
|
17
|
+
for (const name of fixtureFiles) {
|
|
18
|
+
const content: Uint8Array = this.context.resourceManager.getRawFileContentSync(name);
|
|
19
|
+
const file = fs.openSync(filesDir + '/' + name,
|
|
20
|
+
fs.OpenMode.READ_WRITE | fs.OpenMode.CREATE | fs.OpenMode.TRUNC);
|
|
21
|
+
fs.writeSync(file.fd, content);
|
|
22
|
+
fs.closeSync(file);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
关键点:
|
|
28
|
+
- `getRawFileContentSync` 一次性读入 rawfile 全部字节,配合 `fs.writeSync` 写入沙箱 `filesDir`(持久目录)
|
|
29
|
+
- 若库通过 GlobalContext 读取工作目录(如 mp3agic 的 save() 依赖 `path` 键),必须在注入夹具前设置该键
|
|
30
|
+
- 结构简单的样本(如极小 ID3 标签)可改用代码构造字节数组生成,完全不依赖资源文件;样本复杂/体积大时用 rawfile 内置
|
|
31
|
+
|
|
32
|
+
### 结果
|
|
33
|
+
mp3agic 47 个 XTS 用例的 MP3/ID3 样本全部随 HAP 打包注入,免设备手工操作、免外部脚本,CI 可直接复跑。**该模式为夹具交付首选方案;`hdc file send` 降为备选**(仅当夹具体积过大不适合随 HAP 打包时)。
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
## Code Linter 对中文注释的误报模式与已知非阻断项
|
|
2
|
+
|
|
3
|
+
### 问题现象
|
|
4
|
+
|
|
5
|
+
Code Linter 的 `@security/no-commented-code` 规则会将含"代码样式"内容的中文注释(如 `setGenreDescription('Blues') 后 ...` 这类描述性注释)误判为注释掉的代码,产生 P2 级噪音告警。
|
|
6
|
+
|
|
7
|
+
### 解决方案
|
|
8
|
+
|
|
9
|
+
识别为误报,按 P2 噪音处理,不阻断流程。已知非阻断 Warning 清单:
|
|
10
|
+
- `@security/no-commented-code`:中文注释误报(P2 噪音)
|
|
11
|
+
- `@cross-device-app-dev/color-value`:十六进制颜色值写法
|
|
12
|
+
- `file-naming-convention`(`@hw-stylistic/file-naming-convention`):`001_` 序号前缀文件名与要求的大驼峰命名冲突,属工程既有约定
|
|
13
|
+
|
|
14
|
+
### 结果
|
|
15
|
+
|
|
16
|
+
以上 Warning 均不阻塞编译,按 P2 优化项按需处理即可,无需为消除告警改变代码结构或文件命名约定。真正需要修复的是 Error 级问题(0 Error 方可进入编译)。
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
# ESObject 声明 + 泛型构造的实例变量追踪语法级兜底
|
|
2
|
+
|
|
3
|
+
### 问题现象
|
|
4
|
+
|
|
5
|
+
ArkTS 测试代码常见写法:
|
|
6
|
+
|
|
7
|
+
```ts
|
|
8
|
+
let jList: ESObject = new JList<ESObject>(); // 声明类型是 ESObject,非类名
|
|
9
|
+
jList.append(2);
|
|
10
|
+
```
|
|
11
|
+
|
|
12
|
+
基于 `checker.getTypeAtLocation` + `checker.typeToString` 的实例变量追踪依赖类型字符串包含导入类名,但"声明类型为 ESObject + 泛型构造"的组合无法命中(模块解析失败时更是全部失效),导致 `jList.append(2)` 这类"声明变量后调用实例方法"的匹配全部漏报。
|
|
13
|
+
|
|
14
|
+
### 解决方案
|
|
15
|
+
|
|
16
|
+
在 checker 类型推断之外增加**语法级兜底**:遍历 `VariableDeclaration` 时,若 initializer 是 `NewExpression`,直接取 callee 标识符映射到导入类名:
|
|
17
|
+
|
|
18
|
+
```js
|
|
19
|
+
if (node.initializer && ts.isNewExpression(node.initializer)) {
|
|
20
|
+
const callee = node.initializer.expression;
|
|
21
|
+
if (callee && ts.isIdentifier(callee) && importedSymbols.has(callee.text)) {
|
|
22
|
+
const displayName = importedSymbols.get(callee.text) || callee.text;
|
|
23
|
+
if (!varMap[node.name.text]) varMap[node.name.text] = [];
|
|
24
|
+
if (!varMap[node.name.text].includes(displayName)) varMap[node.name.text].push(displayName);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
`NewExpression` 的 `expression`(callee)与类型参数无关,因此天然覆盖泛型构造 `new JList<ESObject>()`,且在 checker 失效(模块解析失败)时依然工作。
|
|
30
|
+
|
|
31
|
+
### 结果
|
|
32
|
+
|
|
33
|
+
mp3agic 案例中 JList 等类的实例方法调用恢复匹配,覆盖率分析输出与人工 grep 盘点逐类一致。经验:基于 TS checker 的分析工具都应准备不依赖 checker 的语法级兜底路径,避免类型推断失效时静默丢失全部匹配。该修复已合入 `analyze-xts-coverage.cjs`(arkts-library-xts-coverage SKILL v1.1.0)。
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# 大小写不敏感文件系统导致模块解析静默失败
|
|
2
|
+
|
|
3
|
+
### 问题现象
|
|
4
|
+
|
|
5
|
+
在 macOS/Windows(大小写不敏感文件系统)上运行基于 TypeScript Compiler API 的分析工具时出现静默失真:
|
|
6
|
+
|
|
7
|
+
1. 库入口候选路径写死为 `library/Index.ets`(大写 I),而库实际文件是小写 `index.ets`
|
|
8
|
+
2. `fs.existsSync('library/Index.ets')` 在大小写不敏感文件系统上返回 `true`,函数返回**错误大小写**的路径
|
|
9
|
+
3. 但内容缓存(`fileContents`)的键来自 `fs.readdirSync` 的**真实小写**路径
|
|
10
|
+
4. 虚拟路径 `.../library/Index.ts` 在缓存中查不到 → `resolveModuleNames` 模块解析失败 → `checker` 类型推断全面失效 → 实例变量追踪返回空 → 所有"声明变量后调用实例方法"的匹配全部丢失
|
|
11
|
+
|
|
12
|
+
**最危险之处**:脚本不报错、不降级,静默输出严重偏低的覆盖率(mp3agic 案例漏报约 84 个接口)。该问题在 Linux(大小写敏感)CI 上不复现——`existsSync` 返回 false 走深度搜索分支,路径行为不同,属于典型的"本机能跑、CI 表现不同"类缺陷。
|
|
13
|
+
|
|
14
|
+
**典型特征信号**:类级覆盖率表中仅静态/工具类有覆盖、所有实例方法类为 0。
|
|
15
|
+
|
|
16
|
+
### 解决方案
|
|
17
|
+
|
|
18
|
+
路径匹配做大小写归一,两选一:
|
|
19
|
+
|
|
20
|
+
```js
|
|
21
|
+
// 方案 A(防御式):精确查找失败后,构建小写键映射表二次查找
|
|
22
|
+
const lowerMap = new Map(Object.keys(fileContents).map(k => [k.toLowerCase(), k]));
|
|
23
|
+
const v = toPosix(candidate.replace(/\.ets$/, '.ts')).toLowerCase();
|
|
24
|
+
if (lowerMap.has(v)) resolvedPath = lowerMap.get(v);
|
|
25
|
+
```
|
|
26
|
+
|
|
27
|
+
方案 B(根治):入口文件定位函数返回前,用 `fs.readdirSync` 的真实文件名做大小写归一,保证虚拟路径键与缓存键严格一致。
|
|
28
|
+
|
|
29
|
+
### 结果
|
|
30
|
+
|
|
31
|
+
mp3agic 案例应用方案 A 后,`@ohos/mp3agic` 模块解析恢复,类型推断生效,实例方法类(EncodedText、ID3v22/23/24Tag 等)覆盖率从 0 恢复正常。大小写归一补丁对大小写敏感平台(Linux)无副作用,可直接合入。该修复已合入 `analyze-xts-coverage.cjs`(arkts-library-xts-coverage SKILL v1.1.0)。
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
## GitCode 仓库 git clone 输出重定向警告属正常行为,不代表克隆失败
|
|
2
|
+
|
|
3
|
+
### 问题现象
|
|
4
|
+
|
|
5
|
+
执行 `git clone https://gitcode.com/CPF-ApplicationTPC/mp3agic` 时输出"警告:重定向到 .../mp3agic.git/",容易被误判为克隆失败,进而触发不必要的降级重试(如去掉 `--depth=1` 重新完整克隆)。
|
|
6
|
+
|
|
7
|
+
### 解决方案
|
|
8
|
+
|
|
9
|
+
该重定向警告是 GitCode 平台的正常行为(GitCode 会自动将无 `.git` 后缀的仓库地址重定向到带 `.git` 后缀的地址),不代表克隆失败。判断克隆是否成功应以命令退出码和目标目录实际内容为准,而非 stderr 警告文本。
|
|
10
|
+
|
|
11
|
+
### 结果
|
|
12
|
+
|
|
13
|
+
克隆实际成功、源码完整。只要 `git clone` 退出码为 0 且目标目录含仓库内容(`.git` 目录、`oh-package.json5` 等),即视为克隆成功,不应因重定向警告触发降级重试,避免浪费时间的无意义完整克隆。
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
# 鸿蒙自动化测试框架关系与文档搜索经验
|
|
2
|
+
|
|
3
|
+
## 一、arkXtest 框架命名混淆
|
|
4
|
+
|
|
5
|
+
### 问题现象
|
|
6
|
+
编写鸿蒙测试文档时,容易将 arkXtest 当作独立框架来描述,误以为存在独立的 arkXtest 包或 API,导致文档中框架名称使用混乱。
|
|
7
|
+
|
|
8
|
+
### 解决方案
|
|
9
|
+
明确 arkXtest 是框架统称而非独立框架。arkXtest = JsUnit + UITest + PerfTest 三者的统称,不存在独立的 arkXtest 包或 API。文档中需区分"统称"与"具体框架"。
|
|
10
|
+
|
|
11
|
+
### 结果
|
|
12
|
+
文档中正确区分框架统称与具体框架,消除 arkXtest 与 JsUnit/UITest 的命名混淆。
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
## 二、JsUnit 与 UITest 关系误判
|
|
17
|
+
|
|
18
|
+
### 问题现象
|
|
19
|
+
不清楚 JsUnit 与 UITest 之间的关系,容易将两者描述为平级框架,误导读者理解测试代码结构。
|
|
20
|
+
|
|
21
|
+
### 解决方案
|
|
22
|
+
理解两者的上下层依赖关系:UITest 脚本必须基于 JsUnit 的 describe/it 定义,在 it 回调中调用 UITest 接口。所有 UITest 测试用例本质上也是 JsUnit 测试用例。文档中使用"底座+上层"模式描述 JsUnit 与 UITest 的关系。
|
|
23
|
+
|
|
24
|
+
### 结果
|
|
25
|
+
文档准确表达 JsUnit(底座)与 UITest(上层)的依赖关系,避免平级错觉。
|
|
26
|
+
|
|
27
|
+
---
|
|
28
|
+
|
|
29
|
+
## 三、Hypium(Python) 与 arkXtest 关系不清
|
|
30
|
+
|
|
31
|
+
### 问题现象
|
|
32
|
+
不清楚 Hypium(Python) 与 arkXtest 体系的关系,难以判断 CI/CD 场景下应选用的测试框架。
|
|
33
|
+
|
|
34
|
+
### 解决方案
|
|
35
|
+
理解两者的完全独立性:Hypium(Python) 运行在 PC 端,通过 hdc 连接设备,不依赖设备端的 JsUnit/UITest 框架。与 arkXtest(设备端框架)完全独立。CI/CD 场景下 Hypium 更适合流水线集成。
|
|
36
|
+
|
|
37
|
+
### 结果
|
|
38
|
+
能根据场景正确选择测试框架:设备端测试用 arkXtest 体系(JsUnit/UITest),流水线集成用 Hypium(Python)。
|
|
39
|
+
|
|
40
|
+
---
|
|
41
|
+
|
|
42
|
+
## 四、API 版本标注遗漏
|
|
43
|
+
|
|
44
|
+
### 问题现象
|
|
45
|
+
标注 UITest API 版本时只标注了一套版本号,导致读者不清楚功能的实际可用范围。
|
|
46
|
+
|
|
47
|
+
### 解决方案
|
|
48
|
+
同时标注两套版本体系:OS API 版本(如 API 8/9/18/20/22)和 @ohos/hypium 包版本(如 1.0.1/1.0.25)。示例:Mock 能力从 @ohos/hypium 1.0.1 开始支持,运行在 API 8+ 设备上。两者缺一不可。
|
|
49
|
+
|
|
50
|
+
### 结果
|
|
51
|
+
版本信息完整,读者可准确判断功能的设备兼容性和包依赖。
|
|
52
|
+
|
|
53
|
+
---
|
|
54
|
+
|
|
55
|
+
## 五、devecocli docs search 中文关键词搜索失败
|
|
56
|
+
|
|
57
|
+
### 问题现象
|
|
58
|
+
使用纯中文关键词搜索 devecocli docs 时返回 SEARCH_FAILED。例如搜索"JsUnit 单元测试"失败。
|
|
59
|
+
|
|
60
|
+
### 解决方案
|
|
61
|
+
改用中英文混合关键词或更通用的关键词。例如搜索"arkXtest 测试框架"和"UiTest UI测试"均成功。
|
|
62
|
+
|
|
63
|
+
### 结果
|
|
64
|
+
搜索成功,获取到所需的鸿蒙测试框架文档。
|
|
65
|
+
|
|
66
|
+
---
|
|
67
|
+
|
|
68
|
+
## 六、devecocli docs search 结果只有摘要
|
|
69
|
+
|
|
70
|
+
### 问题现象
|
|
71
|
+
devecocli docs search 返回的结果只包含摘要,无法获取完整文档内容。
|
|
72
|
+
|
|
73
|
+
### 解决方案
|
|
74
|
+
搜索结果中提取文档 ID,再执行 `devecocli docs read <documentId>` 获取完整文档内容。
|
|
75
|
+
|
|
76
|
+
### 结果
|
|
77
|
+
成功获取完整的文档内容用于分析。
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
# DevEco MCP 构建签名 HAP — 签名配置位置与构建监控经验
|
|
2
|
+
|
|
3
|
+
> 来源知识条目: kn_msovnm6rd46de72c
|
|
4
|
+
> 适用场景: 使用 DevEco MCP 工具(project_sync / build_project)对 HarmonyOS 工程执行同步、构建并生成签名 HAP
|
|
5
|
+
|
|
6
|
+
---
|
|
7
|
+
|
|
8
|
+
## 一、签名配置必须添加到工作区根目录的 build-profile.json5
|
|
9
|
+
|
|
10
|
+
### 问题现象
|
|
11
|
+
在 HarmonyOS 工程的子目录 `build-profile.json5`(如 `rntpc_react-native-pager-view/example/harmony/build-profile.json5`)中添加了 `signingConfigs` 配置后,执行 `deveco-mcp_build_project` 构建时,构建日志仍显示签名被跳过:
|
|
12
|
+
|
|
13
|
+
```
|
|
14
|
+
> hvigor WARN: Will skip sign 'hos_hap'. No signingConfigs profile is configured in current project.
|
|
15
|
+
If needed, configure the signingConfigs in /Users/lalhan/Desktop/3rdLibraryLoop/build-profile.json5.
|
|
16
|
+
```
|
|
17
|
+
|
|
18
|
+
导致产物只有 `entry-default-unsigned.hap`,没有签名 HAP。
|
|
19
|
+
|
|
20
|
+
### 解决方案
|
|
21
|
+
将 `signingConfigs` 配置添加到**工作区根目录**的 `build-profile.json5`(即 DevEco Studio 打开的项目根目录下的文件),而非嵌套子项目中的同名文件。
|
|
22
|
+
|
|
23
|
+
DevEco MCP 的 `build_project` 和 `project_sync` 工具以工作区根目录为项目根,读取的是根级 `build-profile.json5`。
|
|
24
|
+
|
|
25
|
+
根级 `build-profile.json5` 通常包含以下关键字段:
|
|
26
|
+
- `app.products[].signingConfig` — 引用签名配置名
|
|
27
|
+
- `app.signingConfigs[]` — 签名配置数组(需在此处添加签名配置)
|
|
28
|
+
- `modules[].srcPath` — 指向实际 entry 模块路径
|
|
29
|
+
|
|
30
|
+
### 结果
|
|
31
|
+
签名配置被正确读取,构建任务执行 `SignHap`,产物目录下生成 `entry-default-signed.hap`(签名 HAP)。
|
|
32
|
+
|
|
33
|
+
> ⚠️ 注意:根级 `build-profile.json5` 可能使用带引号 key 的标准 JSON 格式,而项目级可能使用 JSON5 无引号 key 格式。两种格式均有效,添加配置时需按各自风格书写。
|
|
34
|
+
|
|
35
|
+
---
|
|
36
|
+
|
|
37
|
+
## 二、利用构建日志 WARN 消息定位签名配置文件
|
|
38
|
+
|
|
39
|
+
### 问题现象
|
|
40
|
+
不确定应该修改哪个 `build-profile.json5` 来添加签名配置时,容易修改错误的文件(子项目级而非根级),导致签名仍然被跳过。
|
|
41
|
+
|
|
42
|
+
### 解决方案
|
|
43
|
+
构建日志中的 WARN 消息会直接给出需要修改的文件路径:
|
|
44
|
+
|
|
45
|
+
```
|
|
46
|
+
If needed, configure the signingConfigs in /Users/lalhan/Desktop/3rdLibraryLoop/build-profile.json5.
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
遇到签名跳过问题时,首先检查构建日志中此 WARN 消息指向的 `build-profile.json5` 路径,在该文件中添加 `signingConfigs`。
|
|
50
|
+
|
|
51
|
+
### 结果
|
|
52
|
+
通过 WARN 消息可直接定位到正确的配置文件路径,避免修改错误文件,快速解决签名跳过问题。
|
|
53
|
+
|
|
54
|
+
---
|
|
55
|
+
|
|
56
|
+
## 三、MCP build_project clean=true 构建超时的监控策略
|
|
57
|
+
|
|
58
|
+
### 问题现象
|
|
59
|
+
调用 `deveco-mcp_build_project` 并设置 `clean=true`(全量清理重建)时,MCP 请求超时:
|
|
60
|
+
|
|
61
|
+
```
|
|
62
|
+
MCP error -32001: Request timed out
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
实际构建在后台继续运行,约 3.5 分钟后完成,但无法直接从 MCP 响应获取构建结果。
|
|
66
|
+
|
|
67
|
+
### 解决方案
|
|
68
|
+
MCP 超时后,通过以下策略监控构建进度并确认结果:
|
|
69
|
+
|
|
70
|
+
1. **监控产物目录**:用 `ls -la` 或 glob 工具检查 `entry/build/default/outputs/default/` 目录,等待 `entry-default-signed.hap` 文件出现。
|
|
71
|
+
2. **检查构建日志**:读取构建日志文件,确认出现 `BUILD SUCCESSFUL` 标记和 `SignHap` 任务完成。
|
|
72
|
+
3. **增量构建策略**:增量构建(不设置 clean)可在 MCP 超时内完成(约 2 秒),但**注意:增量构建无法触发重新签名**,如需重新签名必须 clean 构建。
|
|
73
|
+
|
|
74
|
+
### 结果
|
|
75
|
+
即使 MCP 请求超时,仍可通过监控产物目录和构建日志确认构建成功完成。
|
|
76
|
+
|
|
77
|
+
> ⚠️ 建议:如果修改了签名配置后需要验证签名生效,必须使用 clean=true 进行全量构建,并用监控策略等待完成。
|
|
78
|
+
|
|
79
|
+
---
|
|
80
|
+
|
|
81
|
+
## 四、验证签名成功的快速方法
|
|
82
|
+
|
|
83
|
+
### 问题现象
|
|
84
|
+
构建完成后,如何快速判断签名是否成功应用到 HAP 产物。
|
|
85
|
+
|
|
86
|
+
### 解决方案
|
|
87
|
+
通过以下两种方式快速验证:
|
|
88
|
+
|
|
89
|
+
1. **检查产物文件存在性**:检查 `entry/build/default/outputs/default/` 目录下是否同时存在 `entry-default-signed.hap` 和 `entry-default-unsigned.hap`。如果仅有 unsigned 版本,说明签名被跳过。
|
|
90
|
+
2. **比较文件大小**:签名 HAP 比未签名 HAP 大约 672KB(签名数据):
|
|
91
|
+
|
|
92
|
+
| 文件 | 典型大小 | 差异 |
|
|
93
|
+
|------|----------|------|
|
|
94
|
+
| entry-default-unsigned.hap | ~72,585,629 bytes | 基准 |
|
|
95
|
+
| entry-default-signed.hap | ~73,257,238 bytes | +671,609 bytes(约 672KB 签名数据) |
|
|
96
|
+
|
|
97
|
+
### 结果
|
|
98
|
+
通过文件存在性和大小差异可快速判断签名是否成功应用,无需深入解析 HAP 内部结构。
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
## RN鸿蒙三方库渐进式编译验证经验(netinfo 0.82→0.84)
|
|
2
|
+
|
|
3
|
+
### 问题现象1:codegen脚本添加 --generate-type all 导致编译失败
|
|
4
|
+
|
|
5
|
+
运行 `npm run codegen` 报错 `error: unknown option '--generate-type'`。
|
|
6
|
+
|
|
7
|
+
### 解决方案
|
|
8
|
+
|
|
9
|
+
RNOH 提供两个不同的 codegen 命令,参数支持不同:
|
|
10
|
+
|
|
11
|
+
| 命令 | 用途 | 支持 --generate-type | 使用位置 |
|
|
12
|
+
|------|------|---------------------|---------|
|
|
13
|
+
| `react-native codegen-harmony` | 应用构建阶段 codegen | 不支持 | example/package.json 的 codegen 脚本 |
|
|
14
|
+
| `react-native codegen-lib-harmony` | 库开发阶段 codegen | 支持 | 库根 package.json 的 codegen-lib 脚本 |
|
|
15
|
+
|
|
16
|
+
从 example 的 codegen 脚本中移除 `--generate-type all` 参数。如需使用该参数,应在库根 package.json 中添加 `codegen-lib` 脚本并使用 `react-native codegen-lib-harmony`。
|
|
17
|
+
|
|
18
|
+
### 结果
|
|
19
|
+
|
|
20
|
+
移除参数后 `npm run codegen` 成功生成 5 个文件,`npm run dev` 成功构建 JS bundle,hvigor 构建成功。SKILL 中 0.82→0.84 不兼容变更表标注的"新增 --generate-type all(必选)"影响文件为库根 package.json 的 codegen-lib 脚本,不是 example 工程的 codegen 脚本。
|
|
21
|
+
|
|
22
|
+
---
|
|
23
|
+
|
|
24
|
+
### 问题现象2:npm pack 超时(>120s)
|
|
25
|
+
|
|
26
|
+
rnoh-build-har 执行后在 harmony/ 下产生临时工程文件(oh_modules 913MB、AppScope、build-profile.json5 等)。即使 .npmignore 已排除 harmony/oh_modules,npm pack 仍需遍历整个目录树导致超时。
|
|
27
|
+
|
|
28
|
+
### 解决方案
|
|
29
|
+
|
|
30
|
+
在 npm pack 前清理 rnoh-build-har 产生的临时文件:
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
rm -rf harmony/oh_modules harmony/<module>/build harmony/AppScope harmony/build-profile.json5 harmony/hvigor harmony/oh-package.json5
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
### 结果
|
|
37
|
+
|
|
38
|
+
清理后 npm pack 在数秒内完成。建议在 HAR 构建成功并拷贝到 harmony/<module>.har 后、npm pack 之前执行清理。
|
|
39
|
+
|
|
40
|
+
---
|
|
41
|
+
|
|
42
|
+
### 问题现象3:多任务并行时构建日志来源无法确认
|
|
43
|
+
|
|
44
|
+
多任务并行时,构建日志可能来自不同仓库。需验证日志路径来自当前任务仓库。
|
|
45
|
+
|
|
46
|
+
### 解决方案
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
# 确认当前任务路径在日志中出现(应为大量匹配)
|
|
50
|
+
grep -c "当前任务路径" <log_file>
|
|
51
|
+
# 确认其他任务路径不在日志中(应为 0 匹配)
|
|
52
|
+
grep -c "其他任务路径" <log_file>
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
### 结果
|
|
56
|
+
|
|
57
|
+
本次验证结果:当前任务路径 183 次匹配,其他任务路径 0 次匹配,确认日志来源正确。构建日志应保存到任务仓库目录内,便于验证来源。
|
|
58
|
+
|
|
59
|
+
---
|
|
60
|
+
|
|
61
|
+
### 问题现象4:CMake 编译中断 vs 完整完成无法区分
|
|
62
|
+
|
|
63
|
+
构建日志显示 CMake 在 CMakeTestCCompiler.cmake 阶段报错 ld.lld: error: unknown argument '-search_paths_first',构建在 BuildNativeWithCmake 步骤中断。需判断 CMake 是否完整完成。
|
|
64
|
+
|
|
65
|
+
### 解决方案
|
|
66
|
+
|
|
67
|
+
检查构建日志中以下两个关键步骤是否都存在且无 ERROR:
|
|
68
|
+
- `Finished :entry:default@BuildNativeWithCmake...` — CMake 配置阶段
|
|
69
|
+
- `Finished :entry:default@BuildNativeWithNinja...` — C++ 编译阶段
|
|
70
|
+
|
|
71
|
+
### 结果
|
|
72
|
+
|
|
73
|
+
单一步骤完成不代表 CMake 完整完成,必须同时验证两个步骤。本次 netinfo 构建:CMake 11s 493ms + Ninja 4min 42s 464ms,两者均完整完成。
|
|
74
|
+
|
|
75
|
+
---
|
|
76
|
+
|
|
77
|
+
### 问题现象5:MCP check_ets_files 不支持 .ts 文件
|
|
78
|
+
|
|
79
|
+
MCP 工具 check_ets_files 仅支持 .ets 扩展名,无法对 .ts 文件进行语法检查。
|
|
80
|
+
|
|
81
|
+
### 解决方案
|
|
82
|
+
|
|
83
|
+
.ts 文件需通过实际编译验证语法正确性,无法使用 MCP check_ets_files 工具检查。
|
|
84
|
+
|
|
85
|
+
### 结果
|
|
86
|
+
|
|
87
|
+
对 .ts 文件跳过 MCP 语法检查,直接通过 npm run codegen 和 hvigor 构建验证。
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
## TurboModule 库(非 Fabric 组件)的测试策略差异
|
|
2
|
+
|
|
3
|
+
### 问题现象
|
|
4
|
+
NetInfo 是一个 TurboModule 库,不是 Fabric 组件库。按照 Fabric 组件库的测试策略编写 jest 单元测试时,会出现 mock 策略不匹配的问题:不需要 mock `codegenNativeComponent` 生成的 Fabric 原生组件,但需要 mock `NativeEventEmitter` 和 `NativeModules`(从 `react-native` 导入)。
|
|
5
|
+
|
|
6
|
+
### 解决方案
|
|
7
|
+
TurboModule 库的 jest mock 需求与 Fabric 组件库不同:
|
|
8
|
+
- **不需要** mock `codegenNativeComponent` 生成的 Fabric 原生组件
|
|
9
|
+
- **需要** mock `NativeEventEmitter` 和 `NativeModules`(从 `react-native` 导入)
|
|
10
|
+
- **关键**:`NativeEventEmitter.addListener` 必须返回 `{ remove: () => void }` 对象(模拟 RN 的 `NativeEventSubscription`),而非 Node EventEmitter 的默认返回值。否则 `State.tearDown()` 中的 `this._nativeEventSubscription.remove()` 会报 `TypeError: ...remove is not a function`
|
|
11
|
+
|
|
12
|
+
mock 实现示例:
|
|
13
|
+
```javascript
|
|
14
|
+
// __mocks__/react-native.js
|
|
15
|
+
const { EventEmitter } = require('events');
|
|
16
|
+
class MockNativeEventEmitter extends EventEmitter {
|
|
17
|
+
addListener(eventName, handler) {
|
|
18
|
+
const listener = super.addListener(eventName, handler);
|
|
19
|
+
return { remove: () => super.removeListener(eventName, handler) };
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
### 结果
|
|
25
|
+
TurboModule 库测试通过。这是所有 TurboModule 库通用的 mock 需求:`NativeEventEmitter`(返回 `{remove}` 对象的 `addListener`)、`NativeModules`、`Platform`。
|
|
26
|
+
|
|
27
|
+
---
|
|
28
|
+
|
|
29
|
+
## 导入路径从相对路径到包名的转换
|
|
30
|
+
|
|
31
|
+
### 问题现象
|
|
32
|
+
上游 demo 使用相对路径 `'../src'` 和 `'../../src'` 引用库源码。移植到 example 工程后,这些路径会解析到错误的目录(`example/src/` 自身而非库根目录的 `src/`),导致编译错误或导入了错误的模块。
|
|
33
|
+
|
|
34
|
+
### 解决方案
|
|
35
|
+
将所有导入路径改为包名 `'@react-native-ohos/netinfo'`,让 Metro 的 resolver 正确重定向。批量定位方法:`grep -rl "'../src'" example/src/`
|
|
36
|
+
|
|
37
|
+
### 结果
|
|
38
|
+
所有导入路径正确解析到库源码,编译通过。
|
|
39
|
+
|
|
40
|
+
---
|
|
41
|
+
|
|
42
|
+
## metro.config.js React 单例保护(tgz 包场景)
|
|
43
|
+
|
|
44
|
+
### 问题现象
|
|
45
|
+
即使通过 tgz 包安装(非 symlink 到库根目录),当 `watchFolders` 包含库根目录时,Metro 的 `nodeModulesPaths` 会包含库根目录的 `node_modules/react`,可能在不同导入上下文中解析到不同的 React 实例,导致 hooks 失效崩溃。
|
|
46
|
+
|
|
47
|
+
### 解决方案
|
|
48
|
+
在 `metro.config.js` 中包装 RNOH 的 `resolveRequest`:
|
|
49
|
+
1. 先获取 RNOH 的 `resolveRequest` 引用
|
|
50
|
+
2. 在包装函数中拦截裸 `react` 导入,强制解析到 example 的 `node_modules/react`
|
|
51
|
+
3. 其余导入委托给 RNOH 的 resolver
|
|
52
|
+
|
|
53
|
+
**关键约束**:不能直接设置 `resolveRequest` 覆盖 RNOH 的 harmony 解析器——这会导致 `.harmony.js` 平台文件解析全部失效。必须**包装** RNOH 的 `resolveRequest`,只拦截裸 `react` 导入。
|
|
54
|
+
|
|
55
|
+
验证方法:`grep -oE '(node_modules|\.\./node_modules)/react/index\.js' bundle.harmony.js | sort | uniq -c`,应只有 1 个路径。
|
|
56
|
+
|
|
57
|
+
### 结果
|
|
58
|
+
React 单例保证,hooks 正常工作。
|
|
59
|
+
|
|
60
|
+
---
|
|
61
|
+
|
|
62
|
+
## useNetInfoInstance 的 configuration 参数无限重渲染
|
|
63
|
+
|
|
64
|
+
### 问题现象
|
|
65
|
+
在测试或 demo 中向 `useNetInfoInstance` 传入内联 configuration 对象(如 `<Comp config={{reachabilityShouldRun: () => true}} />`)时,每次渲染都会创建新对象引用,触发 `useEffect` 重新执行,调用 `setNetworkInfoManager(state)` 触发再次渲染,形成无限循环导致 Jest OOM。
|
|
66
|
+
|
|
67
|
+
### 解决方案
|
|
68
|
+
这是上游设计限制。`useNetInfoInstance` 的 `useEffect` 依赖 `[isPaused, configuration]`,内联对象引用每次都不同。测试中需避免传入内联 configuration,应使用 `useMemo` 或将配置定义为模块级常量。
|
|
69
|
+
|
|
70
|
+
### 结果
|
|
71
|
+
避免无限循环,测试正常运行。
|
|
72
|
+
|
|
73
|
+
---
|
|
74
|
+
|
|
75
|
+
## Jest 测试踩坑:mockReset 后 getCurrentState 返回 undefined
|
|
76
|
+
|
|
77
|
+
### 问题现象
|
|
78
|
+
`Cannot read properties of undefined (reading 'isInternetReachable')` 错误。
|
|
79
|
+
|
|
80
|
+
### 解决方案
|
|
81
|
+
`beforeEach` 中 `mockReset()` 后 `getCurrentState` 返回 `undefined`,`configure()` 创建新 State 时构造函数调用 `_fetchCurrentState()` 拿到 undefined。需在 `beforeEach` 中 `mockReset()` 后立即 `mockResolvedValue(defaultState)`。
|
|
82
|
+
|
|
83
|
+
### 结果
|
|
84
|
+
State 初始化正常,不再报 undefined 错误。
|
|
85
|
+
|
|
86
|
+
---
|
|
87
|
+
|
|
88
|
+
## Jest 测试踩坑:fetch() 无参数时 getCurrentState 未被调用
|
|
89
|
+
|
|
90
|
+
### 问题现象
|
|
91
|
+
测试中验证 `fetch()` 调用了 `getCurrentState`,但断言失败——`getCurrentState` 未被调用。
|
|
92
|
+
|
|
93
|
+
### 解决方案
|
|
94
|
+
`latest()` 方法有缓存时直接返回 `Promise.resolve(this._latestState)`,不调用 `getCurrentState`。测试中需要先 emit 事件设置缓存,再验证 `fetch()` 返回缓存值,而非验证 `getCurrentState` 被调用。
|
|
95
|
+
|
|
96
|
+
### 结果
|
|
97
|
+
测试断言正确反映实际行为。
|
|
98
|
+
|
|
99
|
+
---
|
|
100
|
+
|
|
101
|
+
## TurboModule 库的 jest 配置模板
|
|
102
|
+
|
|
103
|
+
### 问题现象
|
|
104
|
+
TurboModule 库同时有 `src/__tests__/` 和 `example/` 目录,jest 配置需要正确处理模块解析和测试文件范围。
|
|
105
|
+
|
|
106
|
+
### 解决方案
|
|
107
|
+
`__mocks__/react-native.js` 中需要提供 `NativeEventEmitter`(返回 `{remove}` 对象的 `addListener`)、`NativeModules`、`Platform`。这是所有 TurboModule 库通用的 mock 需求。
|
|
108
|
+
|
|
109
|
+
库根目录 `jest.config.js` 模板要点:
|
|
110
|
+
- `moduleNameMapper` 统一 `react-native` → mock 和 `react` → 单一路径
|
|
111
|
+
- `testMatch` 精确限定到 `src/__tests__/*.spec.ts`,避免扫描 `example/harmony/oh_modules`
|
|
112
|
+
- `tsconfig.jest.json` 不继承 `@react-native/typescript-config`
|
|
113
|
+
|
|
114
|
+
### 结果
|
|
115
|
+
jest 配置正确,测试扫描范围精确,模块解析统一。
|
|
116
|
+
|
|
117
|
+
---
|
|
118
|
+
|
|
119
|
+
## 测试覆盖率扫描方法(TurboModule 库)
|
|
120
|
+
|
|
121
|
+
### 问题现象
|
|
122
|
+
对于 NetInfo 这种非组件库(TurboModule 库),覆盖率维度与 Fabric 组件库不同,需要不同的扫描方法。
|
|
123
|
+
|
|
124
|
+
### 解决方案
|
|
125
|
+
从 TurboModule Spec 文件(`*Native*.ts`)提取方法列表,从 `src/index.ts` 提取公开导出的函数/hook,然后对照测试文件搜索每个 API 的使用情况。
|
|
126
|
+
|
|
127
|
+
TurboModule 库的覆盖率维度包括:
|
|
128
|
+
- **API 覆盖**:TurboModule spec 中定义的方法
|
|
129
|
+
- **状态类型覆盖**:如网络状态 `cellular`、`wifi`、`none`、`unknown` 等各类型
|
|
130
|
+
- **配置选项覆盖**:如 `useNetInfoInstance` 的 `configuration` 参数各选项
|
|
131
|
+
|
|
132
|
+
### 结果
|
|
133
|
+
覆盖率报告全面覆盖 TurboModule 库的所有维度。
|